zoukankan      html  css  js  c++  java
  • Kruskal算法

    Kruskal算法

    紫书P356

    这是最小生成树(也叫MST)的算法。
    这里的这个排序cmp函数还是比较牛逼的,他是根据w的值排序得到w的下标递增值。
    i.e.这个排序可以保留w数组不动,但又可以得到拍好序的下标值,存在r数组中。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define SI(N) scanf("%d",&(N))
    #define SII(N,M) scanf("%d %d",&(N),&(M))
    #define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
    #define rep(i,b) for(int i=0;i<(b);i++)
    #define rez(i,a,b) for(int i=(a);i<=(b);i++)
    #define red(i,a,b) for(int i=(a);i>=(b);i--)
    const ll LINF = 0x3f3f3f3f3f3f3f3f;
    #define PU(x) puts(#x);
    #define PI(A) cout<<(A)<<endl;
    #define DG(x) cout<<#x<<"="<<(x)<<endl;
    #define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
    #define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
    #define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
    #define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
    const double EPS = 1e-9 ;
    /*  ////////////////////////   C o d i n g  S p a c e   ////////////////////////  */
    const int MAXN = 1000 + 9 ;
    //第i条边的两个端点u v和权值w 和比较的辅助函数r
    int u[MAXN],v[MAXN],w[MAXN],r[MAXN];
    //并查集p
    int p[MAXN];
    int n,m;
    int cmp(const int i,const int j){ return w[i]<w[j];}
    int find(int x){ return p[x]==x?x:p[x]=find(p[x]);}
    int Kruskal(){ 
        int ans=0;
        for (int i=0;i<n;i++) p[i]=i;
        for (int i=0;i<m;i++) r[i]=i;
        PIar(r,m)
        sort(r,r+m,cmp);
        PIar(r,m)
        for (int i=0;i<m;i++){
            int e=r[i];
            int x=find(u[e]);
            int y=find(v[e]);
            if (x!=y){
                ans+=w[e];
                p[x]=y;
            }
        }
        return ans;
    }
    
    void Solve()
    {
        while(cin>>n>>m){
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&u[i],&v[i],&w[i]);
            }
            printf("%d
    ",Kruskal());
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
        freopen("1.out","w",stdout);
    #endif
    //iostream::sync_with_stdio(false);
    //cin.tie(0), cout.tie(0);
        // int T;cin>>T;while(T--)
        Solve();
        return 0;
    }
    

    以下是测试的数据:
    输入
    5 6
    1 5 2
    1 3 2
    5 3 6
    4 3 1
    4 2 3
    2 3 4
    输出
    0 1 2 3 4 5
    3 0 1 4 5 2
    8

  • 相关阅读:
    GO 函数的参数
    GO 函数
    GO 指针
    GO 结构体
    GO 接口
    码云git常用命令
    GO Map的初步使用
    GO Slice
    GO 数组
    GO 键盘输入和打印输出
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6016561.html
Copyright © 2011-2022 走看看