POJ 1182 食物链

来源:互联网 发布:linux系统find查找目录 编辑:程序博客网 时间:2024/06/06 03:17

这题一开始用并查集写,捣鼓了半天不对,于是上网一看用带权并查集,于是乎,就去看带权并查集,然后过来写这题。

用deep[i]表示i到祖先的偏移量,如果x和y是一类的,那么偏移量=0,如果x吃y,那么偏移量=1,如果y吃x,那么偏移量=2(这里的y指的是x的祖先)。根据题意,当d=1时,偏移量为0;当d=2时,偏移量=1。

具体细节在注释中阐述。

#include <cstdio>#include <queue>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N=50005;int father[N],deep[N];void init(){    for(int i=1;i<=N;i++)    {        father[i]=i;        deep[i]=0;    }}int _find(int x){    if(x==father[x])        return x;    int t=father[x];    father[x]=_find(father[x]);    deep[x]=(deep[x]+deep[t])%3;    return father[x];}void _merge(int offset,int x,int y){    int a=_find(x);    int b=_find(y);    if(a!=b)    {        father[a]=b;
//这里也可以画向量图看,路径为a->x->y->b,显然a->x为-deep[x],防止为负值,加上3。        deep[a]=(deep[y]+offset-deep[x]+3)%3;    }}bool judge(int d,int n,int x,int y){    if(x>n||y>n)        return false;    if(d==2&&x==y)        return false;    int a=_find(x),b=_find(y);
//如果a和b不相等,说明x和y之前没有什么关系,显然是正确的。    if(a!=b)        return true;
//如果a和b相等,要想满足条件,则x直接到其祖先的偏移量和x经过y到祖先的偏移量应该相等,这里可以画
//向量图看。    if(deep[x]==(d-1+deep[y])%3)        return true;    else        return false;}int main(){    int n,k,d,x,y;
//这里不要写while(scanf("%d%d",&n,&k)!=EOF),就是因为这个错误,我找了好长时间。    scanf("%d%d",&n,&k);    int ans=0;    init();    for(int i=1;i<=k;i++)    {        scanf("%d%d%d",&d,&x,&y);        if(judge(d,n,x,y)==false)            ans++;        else            _merge(d-1,x,y);    }    printf("%d\n",ans);    return 0;}


0 0
原创粉丝点击