POJ1182 食物链

并查集,relation数组保存当前节点与根节点的关系,0表示当前节点与根节点同类,1当前节点吃根节点,2根节点吃当前节点,关系推导公式可见 poj discuss ,不过由于节点合并方式不一样,所以推导函数有细微的差别。

代码
#include<iostream>
using namespace std;
#define M 50001

int root[M],relation[M];
int findRoot(int x)
{
int t;
if(root[x] != x)
{
t
= root[x];
root[x]
=findRoot(root[x]);
relation[x]
= (relation[x]+relation[t])%3;
}
return root[x];
}

bool IsTrue(int d, int x, int y)
{
int a,b;
a
= findRoot(x);
b
= findRoot(y);
if(a==b)
return (3 + relation[x] - relation[y])%3==d ? true : false;
else
root[b]
=a,relation[b]=(6-d+relation[x]-relation[y])%3;
return true;
}
int main()
{
int i,N,K,d,x,y,ans=0;
scanf(
"%d %d", &N, &K);
for(i=0;i<=N;i++)root[i]=i,relation[i]=0;
for(i=0;i<K;i++)
{
scanf(
"%d %d %d", &d, &x, &y);
if(x>N||y>N||(x==y&&d!=1))ans++;
else if(!IsTrue(d-1,x,y))ans++;
}
printf(
"%d\n", ans);
return 0;
}

 

 

 

posted on 2010-12-02 12:39  ltang  阅读(373)  评论(0编辑  收藏  举报

导航