最小生成树——Kruskal

洛咕博客地址: − &gt; C l i c k H e r e &lt; − -&gt;Click Here&lt;- >ClickHere<,求捧场


万金油 K r u s k a l Kruskal Kruskal

据说 P r i m Prim Prim适用于稠密图?然而好久没写了…… e m m emm emm

算了江一下 K r u s k a l Kruskal Kruskal好了……因为 K r u s k a l Kruskal Kruskal实在是太好理解了……

回顾最小生成树的定义……在一个图中选取若干条边使图连通且边权的和最小

不会的人第一想法肯定是贪心吧……先排个序再瞎搞

K r u s k a l Kruskal Kruskal也就是这样的……不过比纯种贪心多了一些东西……就是并查集,可以用来查询是否连通

这一点很好理解吧,如果两个块已经连通了就不用再选边了

根据上述内容,我们可以写出一个 K r u s k a l Kruskal Kruskal的流程……

1、对所有边按权值从小到大排序

2、遍历每条边

3、判断边两端的块是否连通

4、如果不连通,使答案加上权值,并将两块合并

5、如果连通,跳过

6、重复2~5,直到取的边数到达目标

代码如下

struct Edge
{
	int u,v,dis;
	friend bool operator < (const Edge &x,const Edge &y)
	{
		return x.dis<y.dis;
	}
}t[100005];
int Find(int x)
{
	return x==f[x]?x:f[x]=Find(f[x]);
}
void Merge(int x,int y)
{
	x=Find(x);
	y=Find(y);
	if(x^y) f[x]=y;
}
void Kruskal()
{
	sort(t+1,t+m+1);
	for(int i=1;i<=m;i++)
	{
		int p=Find(t[i].u),q=Find(t[i].v);
		if(p!=q)
		{
			ans+=t[i].dis;
			Merge(p,q);
			num++;
			if(num==n-1) break;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值