食物链------并查集

一个基础的并查集,因为有类似于循环的存在,所以用一个数组,3个区间去存(很巧妙),使得第一个区间吃第二个区间,第二个区间吃第三个区间,第三个区间吃第一个区间。
要注意,如果要对并查集赋值,一定要3个区间的关系均赋值到位。

#include
using namespace std;
const int MX=1e5+9;
int t[MX*3],n,k,order,x,y,ans=0;

int fin(int u){
    return t[u]=(t[u]==u?u:fin(t[u]));
}

int same(int u,int v){
    return fin(u)==fin(v);
}

void unite(int u,int v){
    u=fin(u);
    v=fin(v);
    if( u<v )
        t[v]=u;
    else 
        t[u]=v;
}

int main()
{
  //  freopen("input.txt","r",stdin);
    scanf("%d %d",&n,&k);
    for( int i=1 ; i<=n*3 ; i++ )
        t[i]=i;
    while( k-- ){
        scanf("%d %d %d",&order,&x,&y);
        if( x>n || y>n || (order==2 && x==y ) || x<=0 || y<=0 ){
            ans++;
            continue;
        }
        if( order==1 ){
            if( same(x,y+n) || same(x+n,y) )
                ans++;
            else{
                unite(x,y);
                unite(x+n,y+n);
                unite(x+n*2,y+n*2);
            }
        }
        else{
            if( same(y,x+n) || same(x,y) )
                ans++;
            else{
                unite(x,y+n);
                unite(x+n,y+2*n);
                unite(x+2*n,y);
            }
        }
    }
    printf("%d",ans);
    return 0;
}

你可能感兴趣的:(并查集)