51Nod_1212 无向图最小生成树

                                        51Nod_1212 无向图最小生成树

                                             http://www.51nod.com/Challenge/Problem.html#!#problemId=1212

 

题目

N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。

输入

第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000);第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)

输入

输出最小生成树的所有边的权值之和。

样例输入

9 14
1 2 4
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
2 8 11
3 9 2
7 9 6
3 6 4
4 6 14
1 8 8

样例输出

37

分析

使用kruskal算法进行求解,模板题

C++程序

#include
#include

using namespace std;
const int N=1005;
//并查集
int pre[N];
void init(int n)
{
	for(int i=0;i<=n;i++)
	  pre[i]=i;
}

int find(int x)
{
	int r=x;
	while(r!=pre[r])
	  r=pre[r];
	//路径压缩
	while(x!=pre[x]){
		int i=pre[x];
		pre[x]=r;
		x=i;
	}
	return r; 
}

bool join(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy){
		pre[fx]=fy;
		return true;
	}
	return false;
}

struct Edge{
	int u,v,w;
	Edge(){}
	Edge(int u,int v,int w):u(u),v(v),w(w){}
	bool operator<(const Edge &a)const
	{
		return w>a.w;
	}
};

int main()
{
	int n,m,s,e,w;
	scanf("%d%d",&n,&m);
	init(n);
	priority_queueq;
	while(m--){
		scanf("%d%d%d",&s,&e,&w);
		q.push(Edge(s,e,w));
	}
	int ans=0,cnt=0;
	while(!q.empty()){
		Edge a=q.top();
		q.pop();
		if(join(a.u,a.v)){
			ans+=a.w;
			cnt++;
			if(cnt==n-1)
			  break;
		}
	}
	printf("%d\n",ans);
	return 0;
}

 

你可能感兴趣的:(图论,算法)