hdu1233 繼續暢通工程 (最小生成樹——並查集)
還是暢通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 56352 Accepted Submission(s): 25580
Input 測試輸入包含若幹測試用例。每個測試用例的第1行給出村莊數目N ( < 100 );隨後的N(N-1)/2行對應村莊間的距離,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間的距離。為簡單起見,村莊從1到N編號。
當N為0時,輸入結束,該用例不被處理。
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 繼續暢通工程 (最小生成樹——並查集)