POJ1182

这题需要注意就是 并查集中 相对位置 注意与绝对距离区别

#include<cstdio>
#define maxn 50005
int ans,i,a,b,p,fa,fb,n,k;
int f[maxn],rank[maxn];
int findfather(int x){
    if(f[x]==x)
        return(x);
    else{
        int k=f[x];//保存之前的fa以便之后进行叠加距离
        f[x]=findfather(f[x]);
        rank[x]=(rank[k]+rank[x])%3;
        return(f[x]);
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for(i=1;i<=n;i++){
        f[i]=i;
        rank[i]=0;
    }
    for(i=1;i<=k;i++){
        scanf("%d%d%d",&p,&a,&b);
        if(a>n||b>n||(a==b&&p==2)){
           ans++;
           continue;
        }
        fa=findfather(a);
        fb=findfather(b);
        if(p==1){
            if(fa==fb&&rank[a]!=rank[b])
                ans++;
            if(fa!=fb){
                f[fa]=fb;
                rank[fa]=(rank[b]-rank[a]+3)%3;
                //rank[a]=rank[b];  此处rank[a]表示的是a与fa的距离,因此不能改变,而不能进行更新,下次会更新到。
            }
        }else{
            if(fa==fb&&(rank[a]+1)%3!=rank[b]%3)
                ans++;
            if(fa!=fb){
                f[fa]=fb;
                rank[fa]=(rank[b]-rank[a]+5)%3;
                //rank[a]=(rank[b]+2)%3;
            }
        }
    }
    printf("%d
",ans);
    return 0;
}


原文地址:https://www.cnblogs.com/Mathics/p/3681172.html