并查集

· · 算法·理论

bilibili课程:链接

oiwiki讲解

并查集模板:P3367

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+50;
int n,m;
int x,y,z;
int p[N];
int get_p(int x){
    return p[x]==x?x:p[x]=get_p(p[x]);
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        p[i]=i;
    }
    for(int i=1;i<=m;i++){
        cin>>z>>x>>y;
        if(z==1){
            x=get_p(x);
            y=get_p(y);
            if(x!=y){
                p[x]=y;
            }
        }
        else{
            x=get_p(x);
            y=get_p(y);
            if(p[x]==p[y]){
                cout<<"Y\n";
            }
            else{
                cout<<"N\n";
            }
        }
    }

    return 0;
}

例题:P1111

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[10101010];
struct node{
    int x,y,t;
}road[10101010];
bool cmp(node a,node b){
    return a.t<b.t;
}
int find(int x){
    if(a[x]==x){
        return x;
    }
    else{
        return a[x]=find(a[x]);
    }
}
void joid(int x,int y){
    int q=find(x),w=find(y);
    if (q!=w){
        a[w]=q;
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        a[i]=i;
    }
    for(int i=1;i<=m;i++){
        cin>>road[i].x>>road[i].y>>road[i].t;
    }
    sort(road+1,road+m+1,cmp);
    for(int i=1;i<=m;i++){
        if(find(road[i].x)!=find(road[i].y)){
            joid(road[i].x,road[i].y);
            n--;
        }
        if(n==1){
            cout<<road[i].t<<"\n";
            return 0;
        }
    }
    cout<<"-1\n";

    return 0;
}