1. 程式人生 > >hdu 1233 還是暢通project (克魯斯卡爾裸題)

hdu 1233 還是暢通project (克魯斯卡爾裸題)

pid 要求 -s algo iss eight find 用例 cep

還是暢通project

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 32795 Accepted Submission(s): 14769



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

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

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

Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0

Sample Output
3
5
 
Huge input, scanf is recommended.

Source 浙大計算機研究生復試上機考試-2006年

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1233

解題思路:裸的最小生成樹,克魯斯卡爾,邊權值排序。

代碼例如以下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 1e9
const int maxn=10005;
int fa[maxn];
struct EG
{
	int x,y,w;
}eg[maxn];
void get_fa()
{
 	for(int i=0;i<=maxn;i++)
 		fa[i]=i;
}
int find(int x)
{
	return x==fa[x]?x:find(fa[x]);
}
void Union(int a,int b)
{
	int a1=find(a);
	int b1=find(b);
	if(a1!=b1)
		fa[a1]=b1;
}
int cmp(EG a,EG b)
{
	return a.w<b.w;
}
int main(void)
{
	int a,b,w,n;
	while(scanf("%d",&n)!=EOF&&n)
	{
		get_fa();
		int m=(n*(n-1))/2,ans=0;
		for(int i=0;i<m;i++)
			scanf("%d%d%d",&eg[i].x,&eg[i].y,&eg[i].w);
		sort(eg,eg+m,cmp);
		for(int i=0;i<m;i++)
		{
			if(find(eg[i].x)!=find(eg[i].y))
			{
				Union(eg[i].x,eg[i].y);
				ans+=eg[i].w;
			}
		}
		printf("%d\n",ans);
	}
}


hdu 1233 還是暢通project (克魯斯卡爾裸題)