Kruskal算法

适用范围

最小生成树问题

思路

按照边的权值从小到大排序,然后在不产生圈的前提下不断选取边加入生成树中.判断加入一条边后是否产生圈,只需判断边的两个端点是否已经在一个联通块中,这个过程可以用并查集高效实现.复杂度(ElogV)E边V点.

代码

 1 //并查集代码 
 2 int par[MAX];
 3 int rank[MAX];
 4 
 5 void init(int n) //顶点编号从1开始 
 6 {
 7     for(int i=1;i<=n;i++)
 8     par[i]=i;
 9     return ;
10 }
11 
12 int find(int x)
13 {
14     if(par[x]==x) return x;
15     else return par[x]=find(par[x]);
16 }
17 
18 void unite(int x,int y)
19 {
20     x=find(x),y=find(y);
21     if(x==y) return ;
22     if(rank[x]<rank[y]) par[x]=y;
23     else
24     {
25         par[y]=x;
26         if(rank[x]==rank[y]) rank[x]++;
27     }
28     return ;
29 }
30 //分割线
31 //Kruskal代码 
32 struct edge{int s,t,cost}es[MAX];
33 int n,m;
34 
35 bool cmp(edge a,edge b)
36 {
37     return a.cost<b.cost;
38 }
39 
40 int kruskal(void)
41 {
42     sort(es,es+m,cmp);
43     init(n);
44     int ans=0;
45     for(int i=0;i<m;i++)
46     {
47         if(find(es[i].s)!=find(es[i].t))
48         {
49             unite(es[i].s,es[i].t);
50             ans+=es[i].cost;
51         }
52     }
53     return ans;
54 }

 

转载于:https://www.cnblogs.com/VBEL/p/10710687.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值