ACM PKU 1182 食物链

题目描述:http://poj.org/problem?id=1182

今天上午闲着没事,把这道题的解题思路仔细梳理一下:

题目是中文的,都看懂了,就不多说了。

对于A、B、C三种动物,他们的关系构成了一个环;如图所示,ABC 直接的关系是吃的关系,有向图:

 从三者之间的关系可以看出ABC是轮回对称的,所以只要讨论一个点的关系就够了;

但是对于一个点,仍然存在着三种关系,出了吃别人,和自己被吃之外,还有一个同类型的关系;

对于不能确定两个元素是不是在一个并查集里的情况下,需要进行合并,unionSet()函数来实现;对于X和Y他们的合并需要维护两个数组,一个是并查集的P[]数组,一个是关系数组deff[];

对于x和y,给出一个关系图:

对于同类型,即输入的关系是1的情况,有关系表

同类的关系表

Y1

Y2

Y3

X1

0

2

1

X2

1

0

2

X3

2

1

0

x0,x1,x2分别表示x与px的关系为,x为px的同类,px吃x,x吃px;

x与y属于同类关系说明,如表第一行第一列数据,x1如果和y1是同类的话,那么合并之后,即p[py]=px ;此时px为祖先,跟py的关系为0同类;

                                    第一行第二列数据,x1如果和y2是同类的话,那么合并之后,即p[py]=px ;此时px为祖先,跟py的关系为2,表示py会吃px;

                              第一行第三列数据,x1如果和y3是同类的话,那么合并之后,即p[py]=px ;此时px为祖先,跟py的关系为1,表示px会吃py;

可以的出关系公式为deff[py]=(x-y+3)%3;

对于吃的关系同样可以画出关系表

同类的关系表

Y1

Y2

Y3

X1

1

0

2

X2

2

1

0

X3

0

2

1

 

说明就不写了,自己慢慢推吧,最后的公式是deff[py]=(x-y+4)%3; 

附上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int MAXN=50000;

int p[MAXN+10],d[MAXN];

int N,K,ans;

void init()
{
    for(int i=1; i<=N; i++)
    {
        p[i]=i;
        d[i]=0;
    }
}

int find(int x)
{
    if(p[x]==x)return x;
    int px=find(p[x]);
    d[x]=(d[x]+d[p[x]])%3;
    return p[x]=px;
}

bool unionSet(int x,int y,int D)
{
    int px=find(x);int py=find(y);
    if(px==py)return((d[x]-d[y]+D-1)%3!=0);
    p[py]=px;
    d[py]=(d[x]-d[y]+D+2)%3;
    return false;
}

int main()
{
    freopen("in.txt","r",stdin);
    ans=0;
    scanf("%d%d",&N,&K);
    init();
    for(int i=0,D,x,y; i<K; i++)
    {
        scanf("%d%d%d",&D,&x,&y);
        if(x>N || y>N || (x==y && D==2))
        {
            ans++;
            continue;
        }
        else ans+=unionSet(x,y,D);
    }
    printf("%d\n",ans);
    return 0;
}

  

posted on 2011-08-20 21:23  _Clarence  阅读(418)  评论(0编辑  收藏  举报

导航