hdu 5253 串連的管道(kruskal)(2015年百度之星程式設計大賽,hdu5253
串連的管道Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1323 Accepted Submission(s): 519
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
24 39 12 47 8 5632 32 4321 12 122 334 56 5612 23 4
Sample Output
Case #1:82Case #2:74
Source2015年百度之星程式設計大賽 - 初賽(2)
思路:
最小產生樹,在圖要求全部聯通的情況下求最短的權值,用最短路。想用搜尋之類的要考慮資料大小。
代碼:
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct node{ int x,y,len; bool operator < (const node &a) const { return len < a.len; }};const int N=1100;int x[N][N],m,n,k;int father[N*N];node ve[N*N*4];int Find(int x){ return x==father[x]?x:father[x]=Find(father[x]);}int Union(int x,int y){ int a=Find(x),b=Find(y); if(a!=b) { father[a]=b; return 1; } return 0;}int kruskal(){ node s; int sum=0; for(int i=0;i<k;i++) { if(Union(ve[i].x,ve[i].y)) sum+=ve[i].len; } return sum;}int main(){ int na,ca=1; scanf("%d",&na); while(na--) { k=0; scanf("%d%d",&m,&n); for(int i=0;i<m;i++) for(int j=0;j<n;j++) { node q; father[i*n+j]=i*n+j; scanf("%d",&x[i][j]); if(j>0) { q.x=i*n+j,q.y=i*n+j-1; q.len=abs(x[i][j]-x[i][j-1]); ve[k++]=q; } if(i>0) { q.x=i*n+j,q.y=i*n+j-n; q.len=abs(x[i][j]-x[i-1][j]); ve[k++]=q; } } sort(ve,ve+k); printf("Case #%d:\n",ca++); int xx=kruskal(); printf("%d\n",xx); } return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。