HDU-3371 Connect the Cities(最小生成樹-克魯斯卡爾)

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

題意:就是給出你已知的m條路的長度和k個聯通分量,讓你找出最小的代價讓他們都相通。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 505
#define M 25005
using namespace std;
int per[N];
int ca,n,m,k,p,q,c,t;
struct edge {
	int s;
	int e;
	int val;
} a[M];
int cmp(edge x,edge y) {
	return x.val<y.val;
}
int find(int x) {
	return x==per[x]?x:per[x]=find(per[x]);
//	while(x!=per[x])//while超時,必須壓縮路徑 
//		x=find(per[x]);
//	return x;
}
void Union(int x,int y) {
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
		per[fy]=fx;
}
int Kruscal() {
	int ans=0;
	sort(a,a+m,cmp);
	for(int i=0; i<m; i++) {
		int x=find(a[i].s);
		int y=find(a[i].e);
		if(x!=y)
		{
			ans+=a[i].val;
			per[x]=y;
		}
	}
	int tt=0;
	for(int i=1; i<=n; i++) {
		if(per[i]==i)
			tt++;
		if(tt>1) return -1;
	}
	return ans;
}
int main() {

	scanf("%d",&ca);
	while(ca--) {
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1; i<=n; i++)
			per[i]=i;
		for(int i=0; i<m; i++) {
			scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].val);
		}
	
		while(k--) {
			int t1,t2;
			scanf("%d%d",&t,&t1);
			t--;
			while(t--) {
				scanf("%d",&t2);
				Union(t1,t2);
				t1=t2;
			}
		}
		printf("%d\n",Kruscal());
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章