连接的管道
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:
RE: 题意并不难懂, 数据保存时有点麻烦 。
1 #include2 #include 3 #include 4 #include 5 #include 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 }