连接的管道
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1455 Accepted Submission(s):
549
Problem Description
老 Jack 有一片农田,以往几年都是靠天吃饭的。但是今年老天格外的不开眼,大旱。所以老 Jack
决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行灌溉了。当老 Jack 买完所有铺设在每块农田内部的管道的时候,老 Jack
遇到了新的难题,因为每一块农田的地势高度都不同,所以要想将两块农田的管道链接,老 Jack
就需要额外再购进跟这两块农田高度差相等长度的管道。
现在给出老 Jack农田的数据,你需要告诉老 Jack
在保证所有农田全部可连通灌溉的情况下,最少还需要再购进多长的管道。另外,每块农田都是方形等大的,一块农田只能跟它上下左右四块相邻的农田相连通。
Input
第一行输入一个数字T(T≤10) ,代表输入的样例组数
输入包含若干组测试数据,处理到文件结束。每组测试数据占若干行,第一行两个正整数 N,M(1≤N,M≤1000),代表老 Jack 有N行*M列个农田。接下来 N 行,每行 M 个数字,代表每块农田的高度,农田的高度不会超过100。数字之间用空格分隔。
Output
对于每组测试数据输出两行:
第一行输出:"Case
#i:"。i代表第i组测试数据。
第二行输出 1 个正整数,代表老 Jack 额外最少购进管道的长度。
Sample Input
2
4 3
9 12 4
7 8 56
32 32 43
21 12 12
2 3
34 56 56
12 23 4
Sample Output
Case #1:
82
Case #2:
74
Source
Recommend
hujie | We have carefully selected several similar
problems for you: 5395 5394 5393 5392 5391
RE: 题意并不难懂, 数据保存时有点麻烦 。
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 int num[1100][1100],father[1001000], ac[4][2] ={0, 1, 0, -1, -1, 0, 1, 0}; 8 struct node 9 { 10 int a, b; 11 int w; 12 } map[2001000]; 13 bool cmp(node a, node b) 14 { 15 return a.w < b.w; 16 } 17 void init(int n) 18 { 19 for(int i = 1; i <= n; i++) 20 father[i] = i; 21 } 22 int find(int a) 23 { 24 int r, k, j; 25 r = a; 26 while(r != father[r]) 27 r = father[r]; 28 j = a; 29 while(j != r) 30 { 31 k = father[j]; 32 father[j] = r; 33 j = k; 34 } 35 return r; 36 } 37 bool mercy(int a, int b) 38 { 39 int q = find(a); 40 int p = find(b); 41 if(q != p) 42 { 43 father[q] = p; 44 return true; 45 } 46 else 47 return false; 48 } 49 int main() 50 { 51 // freopen("input.txt","r",stdin); 52 int t, temp = 1; 53 scanf("%d", &t); 54 while(t--) 55 { 56 int n, m, p = 0; 57 scanf("%d %d", &n, &m); 58 init(n*m); 59 // for(int i = 1; i <= n; i++) 60 // for(int j = 1; j <= m; j++) 61 // scanf("%d", &num[i][j]); 62 for(int i = 1; i <= n; i++) /***************/ 63 { 64 for(int j = 1; j <= m; j++) 65 { 66 scanf("%d", &num[i][j]); 67 int a = (i-1)*m + j; 68 if(j > 1) 69 { 70 map[p].a = a; 71 map[p].b = a - 1; 72 map[p++].w = abs(num[i][j] - num[i][j-1]); 73 } 74 if(i > 1) 75 { 76 map[p].a = a; 77 map[p].b = a - m; 78 map[p++].w = abs(num[i][j] - num[i-1][j]); 79 } 80 } 81 } /*********************/ 82 int sum = 0; 83 sort(map, map + p, cmp); 84 int tt = 0; 85 for(int i = 0; i < p; i++) 86 { 87 if(mercy(map[i].a, map[i].b)) 88 { 89 sum += map[i].w; 90 tt++; 91 } 92 if(tt >= n*m-1) //小优化; 93 break; 94 } 95 printf("Case #%d:\n", temp++); 96 printf("%d\n", sum); 97 } 98 return 0; 99 }