克鲁斯卡尔(kruskal)法求最小生成树

kruskal

基本思想:
   算法的第一步是给所有的边按照从小到大的顺序排序。这一步可以直接使用库函数qsort或者sort。接下来从小到大依次
   考察每一条边(u,v)。
具体实现过程如下:
 <1>  设一个有n个顶点的连通图为G(V,E),最初先构造一个只有n个顶点,没有边的非连通图T={V,空}。

 <2> 在G中选择一条具有最小权植的边时,若该边的两个顶点在T中连接不会形成环(环可以用并查集判断(是否为同一个祖
      先)),则将此边加入到T中;否则,将此边舍去(此后永不选用这条边),重新选择一条权植最小的边。(可以先排序)

 <3> 如此重复下去,直到所有顶点在连通为止。
#include<bits/stdc++.h>
using namespace std;
int v[10000010];
struct node
{
	long long int u,v,w;
} a[10000010];

long long int cmp(node a,node b)
{
	return a.w<b.w;
}

long long int dd(int x) // 使用并查集
{
	return v[x]==x?v[x]:v[x]=dd(v[x]);
}

long long int f(int a,int b)
{
	long long int x=dd(a),y=dd(b);
	if(x!=y)
	{
		v[y]=x;
		return 1;
	}
	else return 0;
}

int main()
{
	long long int i,n,m,s=0,temp=0;
	scanf("%lld%lld",&n,&m);
	for(i=0; i<=n+2; i++)	v[i]=i;
	for(i=1; i<=m; i++)
	{
		scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].w);
	}
	sort(a+1,a+1+m,cmp);// 边从小到大排
	for(i=1; i<=m; i++)
	{
		if(temp==n-1) break;//temp表示加入的边的条数,如有n-1条且无环,,则此图定为一棵树
		if(f(a[i].u,a[i].v))//祖先不为同一个,,不会形成环
		{
			temp++;
			s+=a[i].w;
		}
	}
	printf("%lld",s);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值