最小生成树(MST)模板

1.使用结构数组存储所有的边的信息。

2.对所有边按照边的权值进行从小到大排序。

3.根据Kruskal算法,来自不同的分支,找到尽可能小权值的边将其联通起来。也就是说,在边按照权值排序后,每加入一条边,如果这条边的两个结点来自不同分支(采用并查集方式来记录同一分支),则可以使用这条边将两个分支联通。

//最小生成树(Kruskal) 
//还是畅通工程
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 6001
using namespace std; 
int Tree[101];
struct E{
	int A,B;
	int cost;
	bool operator < (const E &e) const{
		return cost<e.cost;
	}
};
int findRoot(int x){
	if(Tree[x]==-1) return x;
	else return findRoot(Tree[x]);
}
E edge[6001];
int main(void){
	int n,m;
	while(cin>>n){
		if(n==0) break;
		for(int i=1;i<=n*(n-1)/2;i++){
			cin>>edge[i].A>>edge[i].B>>edge[i].cost;
		}
		for(int i=1;i<=n;i++){
			Tree[i]=-1;
		}
		sort(edge+1,edge+1+n*(n-1)/2);//排序所有的边 
		int sum=0;
		for(int i=1;i<=n*(n-1)/2;i++){
			int na = edge[i].A;
			int nb = edge[i].B;
			int c = edge[i].cost;
			na = findRoot(na);
			nb = findRoot(nb);//利用并查集来记录它们是否在一个分支 
			if(na!=nb){
				Tree[na]=nb;//没有在同一个分支则合并 
				sum += c;
			}
		}
		cout<<sum<<endl;
	}
	return 0;
}
/*
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
Output:
3
5
*/ 

猜你喜欢

转载自blog.csdn.net/coderwait/article/details/89165309