扩展域并查集经典题

题:https://www.luogu.org/problem/P2024

解析:https://blog.csdn.net/m0_37579232/article/details/79920785

#include<bits/stdc++.h>
using namespace std;
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
typedef long long ll;
const int M=5e4+4;
int f[M],sta[M];//sta[i]==0表i与父亲同级, sta[i]==1表i被父亲吃,sta[i]==2表i吃父亲 
int find(int x){
    if(f[x]==x)
        return x;
    int y=f[x];
    f[x]=find(f[x]);
    sta[x]=(sta[x]+sta[y])%3;
    return f[x];
}
bool check(int x,int y,int sign){
    int a=find(x),b=find(y);
    if(a==b){
        if(sign!=(sta[y]-sta[x]+3)%3)//+3防出现负数 ,可看作向量 
            return false;
        return true;
    }
    f[b]=a;
    sta[b]=(sta[x]-sta[y]+sign+3)%3;
    return true;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        int n,m,countt=0;
        cin>>n>>m;
        for(int i=0;i<=n;i++)
            f[i]=i,sta[i]=0;
        while(m--){
            int op,x,y;
            cin>>op>>x>>y;
            if(op==2&&(x==y)||x>n||y>n){
                countt++;
                continue;
            }
            if(!check(x,y,op-1))
                countt++;
        }
        cout<<countt<<endl;
    } 
    return 0;
    
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/11503837.html