1. 程式人生 > >hdu1233 繼續暢通工程 (最小生成樹——並查集)

hdu1233 繼續暢通工程 (最小生成樹——並查集)

ali std hint 政府 inpu truct class () con

還是暢通工程

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 56352 Accepted Submission(s): 25580



Problem Description 某省調查鄉村交通狀況,得到的統計表中列出了任意兩村莊間的距離。省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可),並要求鋪設的公路總長度為最小。請計算最小的公路總長度。

Input 測試輸入包含若幹測試用例。每個測試用例的第1行給出村莊數目N ( < 100 );隨後的N(N-1)/2行對應村莊間的距離,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間的距離。為簡單起見,村莊從1到N編號。
當N為0時,輸入結束,該用例不被處理。

Output 對每個測試用例,在1行裏輸出最小的公路總長度。

Sample Input

31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50

 

Sample Output

35

Hint
Hint

Huge input, scanf is recommended.

思路:

先建立一個結構體類型變量, 裏面存在a,b,len 代表著城鎮a與城鎮b的距離是len

然後再進行結構體快排(按len從小到大排序)

最後一步進行遍歷,假設存在bin[a],bin[b]的根節點不相等,那麽就執行merger(合並),然後sum+=len.

最後得到的sum就是答案,當然sum首先初始化為0

附上ac:

#include<stdio.h>
#include<stdlib.h>
#define min(a,b) a<b?a:b
struct path{
int s,e,len;
}p[5000];
int f[110];
int find(int x)
{
int r=f[x];
while(r!=f[r])
r=f[r];
return r;
}
void merger(int x,int y)
{
int fx,fy;
fx=find(x);
fy=find(y);
f[fx]=f[fy]=f[x]=f[y]=min(fx,fy);
}
int cmp(const void *a,const void *b)
{
return (* (struct path *)a).len-(*(struct path *)b).len;
}
int main()
{
int n,i,j,sum;
while(scanf("%d",&n),n!=0)
{
int t=n*(n-1)/2;
for(i=0;i<t;i++)
scanf("%d %d %d",&p[i].s,&p[i].e,&p[i].len);
qsort(p,t,sizeof(p[0]),cmp);
j=0;
for(i=1;i<=n;i++)
f[i]=i;
sum=0;
for(i=0;i<t;i++)
{
if(j==n-1)
break;
if(find(p[i].s)==find(p[i].e))
continue;
merger(p[i].s,p[i].e);
sum=sum+p[i].len;
j++;
}
printf("%d\n",sum);
/* for (i=0;i<t;i++)
printf("%d\t%d\t%d\n",path[i].a,path[i].b,path[i].l);*/
}
return 0;
}

hdu1233 繼續暢通工程 (最小生成樹——並查集)