图论:Kruskal算法 求最小生成树

Kruskal算法 求最小生成树
  先构建邻接关系的结构体
struct edge
{
    int u,v,w;
}e[maxn];

  

  因为这个算法利用到了并查集,所以需要构建并查集数组parent[],并且初始化并查集数组parent

int parent[maxn];//并查集

 for(int i=1;i<=n;++i)
    {
        parent[i]=i;//初始化并查集
    }

 

  然后就是很重要的一步,对邻接关系进行排序,注意初始化邻接关系时,虽然是无向图,但是只要记录起点和终点就行,不需要双向的,因为这里最重要的是权值。排序用的是权值进行排序。

初始化邻接关系:

 for(int i=1;i<=m;++i)
    {
        cin>>a>>b>>c;
        e[i].u=a,e[i].v=b,e[i].w=c;
    }//初始化边

排序就需要定义一个排序规则,注意是从小到大

排序规则:

bool cmp(const edge&a,const edge&b)
{
    return a.w<b.w;
}

然后排序:

sort(e+1,e+1+n,cmp);//快排

  排序以后,就是处理每一个邻接关系,遍历每一个邻接关系,如果起点和终点不是同属一个集合,那么就把它们的边权加入mst,并且合并这两个点所在的集合,如果是同一个集合,就跳过,注意这里要定义一个k,记录加入几条边了,每次加入一次mst就++k一次,如果k==n-1,那么就break,退出循环,因为最小生成树中只能有n-1条边。 这里就需要并查集寻找所在集合,和合并集合的函数。

寻找所在集合函数

find:

int find(int x)//查找根节点并且压缩路径
{
    if(parent[x]!=x)
    parent[x]=find(parent[x]);
    return parent[x];
}

合并集合函数:

unions:

void unions(int x,int y)//合并两个集合
{
    parent[find(y)]=find(x);
}

 

处理每一个邻接关系:

for(int i=1;i<=m;++i)
    {
        if(find(e[i].u)!=find(e[i].v))
        {
            ++k;
            mst+=e[i].w;
            unions(e[i].u,e[i].v);
        }
        if(k==n-1)
        break;
    }

 

  完整代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=1e2+5;
 5 int mst,k;
 6 struct edge
 7 {
 8     int u,v,w;
 9 }e[maxn];
10 int parent[maxn];//并查集
11 
12 int find(int x)//查找根节点并且压缩路径
13 {
14     if(parent[x]!=x)
15     parent[x]=find(parent[x]);
16     return parent[x];
17 }
18 
19 void unions(int x,int y)//合并两个集合
20 {
21     parent[find(y)]=find(x);
22 }
23 
24 bool cmp(const edge&a,const edge&b)
25 {
26     return a.w<b.w;
27 }
28 int main()
29 {
30     int n,m;
31     int a,b,c;
32     cin>>n>>m;
33     for(int i=1;i<=m;++i)
34     {
35         cin>>a>>b>>c;
36         e[i].u=a,e[i].v=b,e[i].w=c;
37     }//初始化边
38     for(int i=1;i<=n;++i)
39     {
40         parent[i]=i;//初始化并查集
41     }
42     sort(e+1,e+1+n,cmp);//快排
43     for(int i=1;i<=m;++i)
44     {
45         if(find(e[i].u)!=find(e[i].v))
46         {
47             ++k;
48             mst+=e[i].w;
49             unions(e[i].u,e[i].v);
50         }
51         if(k==n-1)
52         break;
53     }
54     cout<<mst;
55 }

 

posted @ 2022-05-10 15:46  朱朱成  阅读(26)  评论(0编辑  收藏  举报