[poj1182]食物链

题意:a吃b,b吃c,c吃a,给定一系列条件,判断出错的个数。

解题关键:种类并查集。关键是向量的合成。

设0:a与par[a]同类,1:a吃par[a] 2:a被par[a]吃

( 儿子relation + 父亲relation ) % 3 = 儿子对爷爷的relation 

利用这个公式,对向量进行推导即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn=50010;
int par[maxn],rank[maxn];
void init(int n){
    for(int i=0;i<=n;i++){
        par[i]=i;
        rank[i]=0;
    }
}

int find1(int x){
    if(x==par[x]) return par[x];
    int y=find1(par[x]);
    rank[x]=(rank[x]+rank[par[x]])%3;
    return par[x]=y;
}
//环中向量的合成 

int unite(int typ,int x,int y){
    int x1=find1(x);
    int y1=find1(y);
    if(x1==y1){
        if((rank[x]-rank[y]+3)%3==typ-1) return 0;//-rank[y]-(-rank[x])
        return 1;
    }
    par[x1]=y1;
    rank[x1]=(typ-1+rank[y]-rank[x]+3)%3;
    return 0;
}
int main(){
    int n,k,ans,typ,smt1,smt2;
    scanf("%d%d",&n,&k);
    init(n);
    ans=0;
    for(int i=0;i<k;i++){
        scanf("%d%d%d",&typ,&smt1,&smt2);//保证不同 
        if(smt1==smt2&&typ==2) ans++;
        else if(smt1>n||smt2>n) ans++;
        else ans+=unite(typ,smt1,smt2);
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2017-11-05 20:20  Elpsywk  阅读(205)  评论(0编辑  收藏  举报