poj1182食物链 并查集

来源:互联网 发布:快充电池 知乎 编辑:程序博客网 时间:2024/05/01 05:12

    这题与hdu1829做法类似,在一棵树中,用0表示该节点与根节点相同,1表示该节点被根节点吃,-1表示该节点吃根节点。

#include<iostream>#include<cstdio>using namespace std;const int maxn=50005;int set[maxn],c[maxn];//set记录父亲节点,c记录当前节点与根节点的关系//0 :同类 1:被根节点吃 -1:吃根节点void init(int n){    for(int i=1;i<=n;i++)    {        set[i]=i;        c[i]=0;    }}inline int change(int x){    if(x==2)        return -1;    else if(x==-2)        return 1;    else        return x;}int find(int x){    if(set[x]==x)        return x;    int t=set[x];    set[x]=find(t);    c[x]=change(c[x]+c[t]);//路径压缩并更新节点与根节点的关系    return set[x];}bool merge(int x,int y,int d){    int f1=find(x);    int f2=find(y);    if(f1==f2)        return false;    set[f1]=f2;    c[f1]=change((c[y]-d-c[x]+1)%3);//画出食物链可以看出来    return true;}int main(){    int n,m;    int d,a,b,sum=0;    scanf("%d%d",&n,&m);    init(n);    while(m--)    {        scanf("%d%d%d",&d,&a,&b);        if(d==2&&a==b||a>n||b>n)        {            sum++;            continue;        }        //若两种动物处于同一条食物链且不符合当前关系,则为假话        if(!merge(a,b,d)&&change(c[b]-c[a])!=d-1)            sum++;    }    printf("%d\n",sum);    return 0;}


 

原创粉丝点击