先上一波题目 https://www.luogu.org/problem/P2024

通过这道题复习了一波并查集,学习了一波带权值操作

首先我们观察到 所有的环都是以A->B->C->A这样的三元环形式存在的

不同动物之间的关系有三种 同类 吃 被吃 

那么我们用+1表示吃 +2表示被吃 0表示同类就可以很清楚的记录不同动物的关系了

这样我们只需要在合并并查集的时候对路径的权值进行一定的操作 就可以记录不同动物之间的关系以便查询了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=200007;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans=0;
int k,x,y;
int fa[M],d[M];
int find(int x){
    int f=fa[x];
    if(f==x) return x;
    fa[x]=find(f);
    d[x]=(d[f]+d[x])%3;
    return fa[x];
}
int main(){
    n=read(); m=read();
    for(int i=1;i<=n;i++) fa[i]=i,d[i]=0;
    for(int i=1;i<=m;i++){
        k=read(); x=read(); y=read();
        if(x>n||y>n||(k==2&&x==y)){ans++; continue;}
        int p=find(x),q=find(y);
        //puts("qwq");
        //printf("qwq%d %d\n",p,q);
        if(k==1){
            if(p==q){if(d[x]!=d[y]) ans++;}
            else{
                d[p]=(d[y]-d[x]+3)%3;
                fa[p]=q;
            }
        }
        else{
            if(p==q){if(d[x]!=(d[y]+1)%3) ans++;}
            else{
                d[p]=(d[y]-d[x]+4)%3;
                fa[p]=q;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}
View Code
02-01 14:47