poj 1182 食物链

#include <iostream>        
using namespace std;
int n,k,d,x,y,par[50010],rel[50010];
void init()
{
for(int i=1;i<=n;++i)
{
par[i]
=i;
}
memset(rel,
0,sizeof(rel));
}
int Find(int x)
{
int temp_p;
if (par[x] != x)
{
// 因为路径压缩,该结点的与根结点的关系要更新(因为前面合并时可能还没来得及更新).
temp_p = par[x];
par[x]
= Find(par[x]);
// x与根结点的关系更新(因为根结点变了),此时的temp_p为它原来子树的父亲结点.
rel[x] = (rel[x] + rel[temp_p]) % 3;
}
return par[x];
}
void Merge(int a, int b, int p, int q, int d)
{
// 公式是找规律推出来的.
par[p] = q; // 这里的下标相同,都是tree[p].
rel[p] = (rel[b] - rel[a] + 2 + d) % 3;
}
int main()
{
int res=0,p,q;
cin
>>n>>k;
init();
while(k--)
{
scanf(
"%d%d%d",&d,&x,&y);
if(x>n||y>n) //if(x>n||y>n)要放在前面,因为d==1&&x==y时有可能x==y>n
res++;
else if(d==1&&x==y)
continue;
else if(d==2&&x==y)
res
++;
else
{
p
=Find(x);
q
=Find(y);
if(p!=q)
{
Merge(x,y,p,q,d);
}
else
{
if ((rel[y] + d + 2) % 3 != rel[x] )
res
++;
}
}
}
cout
<<res<<endl;
return 0;
}

//见于 http://hi.baidu.com/czyuan_acm/blog/item/531c07afdc7d6fc57cd92ab1.html

  

posted on 2011-07-20 22:35  sysu_mjc  阅读(126)  评论(0编辑  收藏  举报

导航