POJ 1182 食物链(并查集+逻辑关系)

来源:互联网 发布:音响调试软件 编辑:程序博客网 时间:2024/06/08 03:00

大意:存在三种生物A吃B, B吃C,C吃A。

有两种语句1 x y:说明x与y为同类

                    2 x y:说明x吃y

根据规则来判断下面说的话存不存在假话,最后输出假话的值。

判断为假话的条件:

1) 当前的话与前面的某些真的话冲突,就是假话;
2) 当前的话中X或Y比N大,就是假话;
3) 当前的话表示X吃X,就是假话。

题意:

POJ2492的升级版,关系变得更复杂((⊙﹏⊙)b)。

建立关系数组s,0为同类,1为吃,2为被吃。

在输入符合规则的情况下只有:

            1类语句中x与y在同一集合且对应根节点的关系不同。

             2类语句中x与y在同一集合且不满足x对应根节点关系与y对应根节点关系为吃

           (fx=x对应根节点关系,fy=y对应根节点关系,fx=1 fy=0,fx=2 fy=1,fx=0 fy=2。的情况才为真话)

不在同一集合的情况要根据根节点的关系进行合并(要将关系理清楚,觉得有点复杂拿笔推一推都列出来好了)

#include <iostream>#include <vector>#include <string.h>#include <stdio.h>using namespace std;int n;int f[60000],rank[60000],s[60000];int find(int x,int &s1){    int t=x;    s1=0;    while(x!=f[x])    {        if(s[x]==1)        {            s1++;            if(s1>2)                s1=0;        }        else if(s[x]==2)        {            s1--;            if(s1<0)                s1=2;        }        x=f[x];    }    f[t]=x;    s[t]=s1;//路径压缩    return x;}bool judge(int t,int x,int y){    int sx,sy;    int fx=find(x,sx);    int fy=find(y,sy);    if(t==1)    {        if(fx==fy)        {            if(sx==sy)                return 1;            else                return 0;        }        else        {            f[fy]=fx;            if(sy==0)                s[fy]=sx;            else if(sx==0)            {                if(sy==1)                    s[fy]=2;                else if(sy==2)                    s[fy]=1;            }            else if(sx==sy)                s[fy]=0;            else if(sx==1&&sy==2)                s[fy]=2;            else                s[fy]=1;            return 1;        }    }    else if(t==2)    {        if(fx==fy)        {            if((sx==1&&sy==0)||(sx==2&&sy==1)||(sx==0&&sy==2))                return 1;            else                return 0;        }        else        {            f[fy]=fx;            if(sy==0&&sx==0)                s[fy]=2;            else if(sy==0&&sx==1)                s[fy]=0;            else if(sy==0&&sx==2)                s[fy]=1;            else if(sy==1&&sx==0)                s[fy]=1;            else if(sy==1&&sx==1)                s[fy]=2;            else if(sy==1&&sx==2)                s[fy]=0;            else if(sy==2&&sx==0)                s[fy]=0;            else  if(sy==2&&sx==1)                s[fy]=1;            else if(sy==2&&sx==2)                s[fy]=2;            return 1;        }    }}int main(){    int m,t,x,y;    scanf("%d%d",&n,&m);    int ans=0;    for(int i=1;i<=n;i++)         f[i]=i,s[i]=0;    for(int i=0; i<m; i++)    {        scanf("%d%d%d",&t,&x,&y);        if(x>n||y>n)            ans++;        else if(t==2&&x==y)            ans++;        else if(!judge(t,x,y))            ans++;    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击