题目链接

C. Dungeons and Candies
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

During the loading of the game "Dungeons and Candies" you are required to get descriptions of k levels from the server. Each description is a map of an n × m checkered rectangular field. Some cells of the field contain candies (each cell has at most one candy). An empty cell is denoted as "." on the map, but if a cell has a candy, it is denoted as a letter of the English alphabet. A level may contain identical candies, in this case the letters in the corresponding cells of the map will be the same.

When you transmit information via a network, you want to minimize traffic — the total size of the transferred data. The levels can be transmitted in any order. There are two ways to transmit the current level A:

  1. You can transmit the whole level A. Then you need to transmit n·m bytes via the network.
  2. You can transmit the difference between level A and some previously transmitted level B (if it exists); this operation requires to transmit dA, B·w bytes, where dA, B is the number of cells of the field that are different for A and B, and w is a constant. Note, that you should compare only the corresponding cells of levels A and B to calculate dA, B. You cannot transform the maps of levels, i.e. rotate or shift them relatively to each other.

Your task is to find a way to transfer all the k levels and minimize the traffic.

Input

The first line contains four integers n, m, k, w (1 ≤ n, m ≤ 10; 1 ≤ k, w ≤ 1000). Then follows the description of k levels. Each level is described by n lines, each line contains m characters. Each character is either a letter of the English alphabet or a dot ("."). Please note that the case of the letters matters.

Output

In the first line print the required minimum number of transferred bytes.

Then print k pairs of integers x1, y1, x2, y2, ..., xk, yk, describing the way to transfer levels. Pair xi, yi means that level xi needs to be transferred by way yi. If yi equals 0, that means that the level must be transferred using the first way, otherwise yi must be equal to the number of a previously transferred level. It means that you will transfer the difference between levels yi and xi to transfer level xi. Print the pairs in the order of transferring levels. The levels are numbered 1 through k in the order they follow in the input.

If there are multiple optimal solutions, you can print any of them.

Sample test(s)
Input
2 3 3 2
A.A
...
A.a
..C
X.Y
...
Output
14
1 0
2 1
3 1
Input
1 1 4 1
A
.
B
.
Output
3
1 0
2 0
4 2
3 0
Input
1 3 5 2
ABA
BBB
BBA
BAB
ABB
Output
11
1 0
3 1
2 3
4 2
5 1
解题思路: 以第i个level为结点i, 并增加一个0作为采用第一种方式上传level, 每个点(1...k)到标记为0的点的边权为n * m, 
      其他从i点到j点的边权为diff(level i, level j), 也就是第i个level和第j个level不同的个数,
      然后求一遍MST(最小生成树)即可。
Accepted Code:
 /*************************************************************************
> File Name: 436C.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年06月24日 星期二 17时03分36秒
> Propose:
************************************************************************/ #include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; #define INF (0x3f3f3f3f)
int n, m, k, w;
char a[][][];
int cost[][], d[], from[];
bool used[];
vector<int> OoO; int
dist(int x, int y) {
int cnt = ;
for (int i = ; i < n; i++)
for (int j = ; j < m; j++)
if (a[x][i][j] != a[y][i][j]) cnt++;
return cnt;
} int
main(void) {
ios_base::sync_with_stdio(false);
while (~scanf("%d %d %d %d", &n, &m, &k, &w)) {
for (int i = ; i <= k; i++)
for (int j = ; j < n; j++) scanf("%s", a[i][j]); for (int i = ; i <= k; i++) {
for (int j = i+; j <= k; j++) {
cost[i][j] = cost[j][i] = dist(i, j) * w;
}
cost[i][] = cost[][i] = m * n;
}
memset(used, false, sizeof(used));
memset(d, 0x3f, sizeof(d));
d[] = ;
int ans = ;
OoO.clear();
while (true) {
int v = -;
for (int u = ; u <= k; u++) {
if (!used[u] && (v==- || d[v] > d[u])) {
v = u;
}
}
if (v == -) break;
used[v] = true;
ans += d[v];
for (int u = ; u <= k; u++) if (!used[u] && d[u] > cost[u][v]){
d[u] = cost[u][v];
from[u] = v;
}
OoO.push_back(v);
}
printf("%d\n", ans);
for (int i = ; i <= k; i++) {
printf("%d %d\n", OoO[i], from[OoO[i]]);
}
} return ;
}





												

Codeforces 436C的更多相关文章

  1. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  2. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  3. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  4. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  5. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  6. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  7. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  8. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

  9. CodeForces - 148D Bag of mice

    http://codeforces.com/problemset/problem/148/D 题目大意: 原来袋子里有w只白鼠和b只黑鼠 龙和王妃轮流从袋子里抓老鼠.谁先抓到白色老鼠谁就赢. 王妃每次 ...

随机推荐

  1. 如何撤销Git操作?

    本文不再更新,可能存在内容过时的情况,实时更新请移步我的新博客:如何撤销Git操作?: Git 版本管理时,往往需要撤销某些操作. 本文介绍几种最主要的情况,给出详细的解释.更多的命令可以参考< ...

  2. vim 插入行号

    :let i=1000000|g/^/s//\=i.' '/|let i=i+1

  3. LUOGU P2675 《瞿葩的数字游戏》T3-三角圣地

    题面 解题思路 手推可以得出,最后每个数字的贡献其实就是第n行杨辉三角数,然后直接卢卡斯直接算(今天才找到lucas定理时间复杂度是log n,log以模数为底).代码略麻烦,不想改了. 代码 #in ...

  4. 深入浅出 Java Concurrency (10): 锁机制 part 5 闭锁 (CountDownLatch)[转]

    此小节介绍几个与锁有关的有用工具. 闭锁(Latch) 闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态.通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻 ...

  5. linux学习(四)-----linux常用指令

    touch 指令 touch 指令创建空文件 基本语法 touch 文件名称 应用实例 案例 1: 创建一个空文件 hello.txt cp 指令 cp 指令拷贝文件到指定目录 基本语法 cp [选项 ...

  6. jeeCMS首页加载流程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/gyshun/article/details/79669293 如果JEECMS部署完毕之后,在浏览器 ...

  7. MyISAM 与 innoDB 的选择

    1.MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.不 ...

  8. Spring AOP(一)--基本概念

    AOP(Aspect Oriented Programing),意为面向切面编程,其实看了很多书本的介绍和说明,我觉得这些解释都太过书面,也可能是翻译的原因,总觉得还是不太懂,也难以理解这种叫法,尤其 ...

  9. WhaleCTF之web密码泄露

    WhaleCTF之密码泄露 前往题目 没有思路,习惯看一下源码,拉到最后,发现有惊喜 直接把index.php 换成password.txt,访问 这是要让我密码爆破吗?直接把密码保存成passwor ...

  10. web api中允许跨域访问

    ①添加owin的引用 ②添加owin.Cors的引用 ③在WebApiConfig中添加 config.EnableCors(new EnableCorsAttribute("*" ...