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 ;
}

 

 

 

你可能感兴趣的:(poj)