洛谷

https://www.luogu.org/problemnew/solution/P1111

并查集的水题,水题都错了好多发。

首先并不是有环就退出,而是连通分支为1才退出,每次合并成功连通分支才会减1

还有一个bug就是假如没有到达连通分支为1,不应该输出maxt而是要输出-1。所以应该是在cnt==1的情况再更新maxt并break才对。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int n,m;
struct edge{
    int x,y,t;
    bool operator<(edge that){
        return t<that.t;
    }
}e[100005];

int p[1005];
int _rank[1005];
struct union_find_set{
    void init(){
        for(int i=1;i<=1000;i++){
            p[i]=i;
            _rank[i]=1;
        }
    }

    int _find(int x){
        if(p[x]!=x)
            return p[x]=_find(p[x]);
        else
            return x;
    }
    bool union_set(int x,int y){
        int fx=_find(x);
        int fy=_find(y);
        if(fx==fy){
            return false;
        }
        else{
            if(_rank[fx]<=_rank[fy]){
                if(_rank[fx]==_rank[fy])
                    _rank[fy]++;
                p[fx]=fy;
            }
            else{
                p[fy]=fx;
            }
            return true;
        }
    }
};

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++){
        scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].t);
    }

    sort(e,e+m);

    union_find_set s;
    s.init();

    int maxt=-1;
    int cnt=n;
    for(int i=0;i<m;i++){
        if(s.union_set(e[i].x,e[i].y)==false){
            maxt=e[i].t;
        }
        else{
            maxt=e[i].t;
            cnt--;
            if(cnt==1)
                break;
        }
    }

    /*if(maxt==-1){
        maxt=e[m-1].t;
        for(int i=1;i<=n;i++){
            s._find(i);
        }
        for(int i=2;i<=n;i++){
            if(p[i]!=p[i-1]){
                maxt=-1;
                break;
            }
        }
    }*/

    if(cnt!=1)
        maxt=-1;

    printf("%d
",maxt);
}

.

原文地址:https://www.cnblogs.com/Yinku/p/10306475.html