无向图的最小生成树之Kruskal算法

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

Input第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)Output输出最小生成树的所有边的权值之和。Sample Input

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

Sample Output

37

 

#include<bits/stdc++.h>
using namespace std;
#define maxn 50005
#define INF 0x3f3f3f3f
int par[maxn],rank[maxn];
struct edge//边的信息 
{
	int u,v,cost;
}es[maxn];
bool cmp(edge a,edge b)
{
	return a.cost<b.cost;
}
int init(int n)//初始化 
{
	for(int i=0;i<n;i++)
	{
		par[i]=i;
		rank[i]=1;
	}
}
int find(int x)//查询节点函数 
{
	if(par[x]==x)
	{
		return x;
	}
	else
	{
		return par[x]=find(par[x]);
	}
}
void unite(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]++;
		}
	}
}
bool same(int x,int y)//判断是否 在同一个连通分量里面 
{
	return find(x)==find(y);
}
int main()
{
	int n,m,res=0;
	scanf("%d %d",&n,&m);
	for(int i=0;i<m;i++)
	{
		scanf("%d %d %d",&es[i].u,&es[i].v,&es[i].cost);
	}
	sort(es,es+m,cmp);//按照权值排序 
	init(n);//初始化 
	for(int i=0;i<m;i++)
	{
		edge e=es[i];
		if(!same(e.u,e.v))
		{
			unite(e.u,e.v);
			res+=e.cost;
		}
	}
	printf("%d\n",res);
	return 0;
}



 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值