14 条题解

  • 6
    @ 2021-9-14 20:38:38

    使用 Kruskal 算法解决。

    主要思路:把边以边权从小到大排序。接下来从头开始枚举边。如果边会使得后面的图一定不是树(即出现环),则跳过。如果总共已经 n1n-1 条边,则结束。如果所有枚举完后不到 n1n-1 条边,则返回不行(此题没有)。

    那么如何判断是否有环?最好的方法就是使用优化的并查集。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int m,n,cnt,sum;
    int fa[100009];
    struct edge{
        int w;
        int u,v;
    };
    edge e[200009];
    bool cmp(edge x,edge y){
        return x.w<y.w;
    }
    void init(){
        cin>>n>>m;
        for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].w;
        for(int i=1;i<=n;i++) fa[i]=i;
    }
    int anc(int k){
        if(fa[k]==k) return k;
        else return fa[k]=anc(fa[k]);
    }
    void relate(int x,int y){
        if(x<y) swap(x,y);
        fa[anc(y)]=anc(x);
    }
    signed main(){
        init();
        sort(e+1,e+m+1,cmp);
        for(int i=1;i<=m;i++){
            if(anc(e[i].u)!=anc(e[i].v)){
                cnt++;
                relate(e[i].u,e[i].v);
                sum+=e[i].w;
            }
            if(cnt==n-1) break;
        }
        if(cnt!=n-1) cout<<"No solution";
        else cout<<sum;
        return 0;
    }
    

    信息

    ID
    91
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    883
    已通过
    293
    上传者