zoukankan      html  css  js  c++  java
  • 最小生成树kruskal POJ 3522 Slim Span

    题目:https://odzkskevi.qnssl.com/8e16f8701018d0e3529ac3ca319e1f67?v=1502277241
    最简单的kruskal,主要参考紫书代码
    kruskal算法就是先给边按权值大小排序,然后从小到大遍历,用并查集判断边上的两个点是否在同一集合,如果不是的话将其添加进去,直到所有的点都加入到集合中。

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    const int maxn=10000;
    int u[maxn],v[maxn],w[maxn],r[maxn],p[105];
    int n,m;
    bool cmp(int a,int b)
    {
        return w[a]<w[b];
    }
    int find(int x)
    {
        return p[x]==x?x:p[x]=find(p[x]);
    }
    int kruskal()
    {
        int ans=INF,ok=0;
        for(int i=1;i<=n;i++) p[i]=i;
        for(int i=0;i<m;i++) r[i]=i;
        sort(r,r+m,cmp);                  //间接排序
        for(int i=0;i<m;i++)
        {
            int num=0;
            for(int j=1;j<=n;j++) p[j]=j;
            for(int j=i;j<m;j++)
            {
                int e=r[j],x=find(u[e]),y=find(v[e]);
                if(x!=y)               
                {
                    p[x]=y;
                    num++;
                }
                if(num==n-1)
                {
                    ans=min(ans,w[r[j]]-w[r[i]]);
                    ok=1;
                    break;
                }
            }
        }
        if(ok==1)
            return ans;
        else
            return -1;
    }
    int main()
    {
        while(cin>>n>>m)
        {
            if(n==0)
                break;
            for(int i=0;i<m;i++)
                cin>>u[i]>>v[i]>>w[i];
            cout<<kruskal()<<endl;
        }
    }
  • 相关阅读:
    [CF1106E] 边界有问题
    UOJ 67 新年的毒瘤
    BZOJ 1093 [ZJOI2007]最大半连通子图
    codeforces round#510
    codeforces round#509
    杂谈
    BZOJ 3007 [SDOI2012]拯救小云公主
    BZOJ 1799
    BZOJ 3329
    BZOJ 3209 花神的数论题
  • 原文地址:https://www.cnblogs.com/acagain/p/9180728.html
Copyright © 2011-2022 走看看