POJ-2421 Constructing Roads(最小生成树问题)

原题链接: http://poj.org/problem?id=2421

在这里插入图片描述
测试样例

Sample Input
3
0 990 692
990 0 179
692 179 0
1
1 2
Sample Output
179

题意: N个村庄需要修路,请你找出最少花费。

解题思路: 最小生成树模板题,我们要细心,理解其中原理,这里指路一篇blog:Kruskal算法

AC代码

/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<iostream>//POJ不支持
#include<algorithm>

#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=a;i>=n;i--)

using namespace std;

const int inf=0x3f3f3f3f;//无穷大。
const int maxn=1e5;//限定值。
typedef long long ll;

int n;
int father[maxn];
struct node{
	int u,v,w;
	bool operator<(const node&a){
		return w<a.w;
	}
};
int Find(int x){
	int r=x;
	while(r!=father[r]){
		r=father[r];
	}
	int i=x,j;
	while(father[i]!=r){
		j=father[i];
		father[i]=r;
		i=j;
	}
	return r;
}
int main(){
	while(cin>>n){
		node pays[maxn];
		int cnt=0;
		int u,v,w;
		rep(i,1,n){
			rep(j,1,n){
				cin>>w;
				if(i!=j){
					pays[cnt].u=i,pays[cnt].v=j,pays[cnt].w=w;
					cnt++;
				}
			}
		}
		rep(i,1,n){
			father[i]=i;
		}
		int q;
		cin>>q;
		int fu,fv;
		while(q--){
			cin>>u>>v;
			fu=Find(u),fv=Find(v);
			if(fu!=fv){
				father[fu]=fv;
			}
		}
		sort(pays,pays+cnt);
		int ans=0;
		rep(i,0,cnt-1){
			fu=Find(pays[i].u),fv=Find(pays[i].v);
			if(fu!=fv){
				ans+=pays[i].w;
				father[fu]=fv;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2022-03-26 16:49  unique_pursuit  阅读(13)  评论(0)    收藏  举报