1. 程式人生 > >最小生成樹---Kruskal演算法---挑戰程式設計競賽讀書筆記

最小生成樹---Kruskal演算法---挑戰程式設計競賽讀書筆記

測試資料也一樣。

這個演算法用到並查集來高效的判斷頂點u,v是否屬於同一個聯通分量。

程式碼:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <fstream>
using namespace std;
const int max_e=100;
const int max_v=100;
const int inf=99999;

struct edge{
	int from,to,weight;
} ;
edge es[max_e];
bool cmp(const edge &a,const edge &b){
	return a.weight<b.weight;
}
int V,E;	//V vertexs,{1,2,3...n}, E edges.

// union_set 
int par[max_v],rank[max_v];
void inin_union_set(int v)
{
	for(int i=1;i<=v;i++){
		par[i]=i;
		rank[i]=0;
	}
}
int find(int x){
	if(par[x]==x)return x;
	else return par[x]=find(par[x]);
	
}
void union_set(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y)return ;
	if(rank[x]<rank[y]){
		par[x]=y;
	}
	else {
		par[y]=x;
		if(rank[x]==rank[y]) rank[x]++; 
	}
}
int Kruskal()
{
	sort(es,es+E,cmp);
	inin_union_set(V);
	int res=0;
	for(int i=0;i<E;i++)
	{
		edge e=es[i];
		if( find(e.from)!=find(e.to) )
		{
			union_set(e.from,e.to);
			res+=e.weight;
		}
	}
	return res;
}
int main()
{
	ifstream fin;
	fin.open("input.txt");
	while(fin>>V>>E)
	{
		for(int i=0;i<E;i++){
			fin>>es[i].from>>es[i].to>>es[i].weight;
			
		}
		cout<<Kruskal()<<endl;
	}
	return 0;
}