问题:

Kruskal算法构造最小生成树的过程。

解析:

Kruskal算法的基本思路:

对于所有的边,每次取一条最短的边(不能重复取),判断它的两个端点是否已经在一个连通块中了(并查集维护),如果是,那么取下一条边;如果没在一个连通块中,则把两个连通块(不一定是两个点)连在一起,答案加上当前边的长度。直到所有的点都在一个连通块中结束。

解析图:

 设计(核心代码):

 1 int kruskal()
 2 {
 3     for(int i=1;i<=tot;++i)    q.push(p[i]);//把所有的边放入优先队列
 4     while(cnt!=n-1)
 5     {
 6         edge x=q.top();
 7         q.pop();
 8         while(find(x.u)==find(x.v))    x=q.top(),q.pop();
 9         ba(x.u,x.v);
10         cnt++;
11         ans+=x.w;
12     }
13     return ans;
14 }

源码:

https://github.com/Big-Kelly/Algorithm

  1 #include<bits/stdc++.h>
  2 #include <set>
  3 #include <map>
  4 #include <stack>
  5 #include <cmath>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 
 14 #define ll long long
 15 #define PLL pair<ll,ll>
 16 #define PII pair<int,int>
 17 #define bug printf("*********\n")
 18 #define FIN freopen("input.txt","r",stdin);
 19 #define FON freopen("output.txt","w+",stdout);
 20 #define IO ios::sync_with_stdio(false),cin.tie(0)
 21 #define ls root<<1
 22 #define rs root<<1|1
 23 
 24 using namespace std;
 25 const int inf=0x3f3f3f3f;
 26 const ll Inf=1e18+7;
 27 const int maxn=1e4+5;
 28 const int mod=1e9+7;
 29 
 30 struct Kruskal
 31 {
 32     //结构体存边
 33     struct edge
 34     {
 35         int u,v,w;
 36     }p[maxn];
 37 
 38     int tot;
 39 
 40     void add(int u,int v,int w)
 41     {
 42         p[++tot].v=v;
 43         p[tot].w=w;
 44         p[tot].u=u;
 45     }
 46 
 47     int fa[maxn],n;//并查集。
 48 
 49     void init()//初始化
 50     {
 51         tot=0;
 52         for(int i=1;i<=n;++i)    fa[i]=i;
 53     }
 54 
 55     //优先队列处理最短边
 56     struct cmp
 57     {
 58         bool operator()(const edge &a,const edge &b)
 59         {
 60             return a.w>b.w;
 61         }
 62     };
 63     priority_queue<edge,vector<edge>,cmp > q;
 64 
 65     //并查集
 66     int find(int x)
 67     {
 68         return fa[x]==x?x:fa[x]=find(fa[x]);
 69     }
 70 
 71     void ba(int x,int y)
 72     {
 73         int px=find(x),py=find(y);
 74         fa[px]=py;
 75     }
 76 
 77     int ans=0,cnt=0;
 78 
 79     int kruskal()
 80     {
 81         for(int i=1;i<=tot;++i)    q.push(p[i]);//把所有的边放入优先队列
 82         while(cnt!=n-1)
 83         {
 84             edge x=q.top();
 85             q.pop();
 86             while(find(x.u)==find(x.v))    x=q.top(),q.pop();
 87             ba(x.u,x.v);
 88             cnt++;
 89             ans+=x.w;
 90         }
 91         return ans;
 92     }
 93 };
 94 
 95 int n,m;
 96 
 97 int main()
 98 {
 99     freopen("in.txt","r",stdin);
100     freopen("out.txt","w",stdout);
101     Kruskal k;
102     scanf("%d %d",&n,&m);
103     k.n=n;
104     k.init();
105     while(m--)
106     {
107         int u,v,w;
108         scanf("%d %d %d",&u,&v,&w);
109         k.add(u,v,w);
110     }
111     printf("%d\n",k.kruskal());
112 }
View Code

 

posted on 2020-02-29 14:41  Big-Kelly  阅读(139)  评论(0编辑  收藏  举报