Description
Input
Output
Sample Input
100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5
Sample Output
3
思路:根据题意想A,B,C构成mod3的关系,如果D=2表示x吃y,这时会出问题:x吃y,y吃z,那么x到z的关系为4%3=1,于是x到z的关系为x与y是同类;
但是z到x的关系为3-1=2,即z吃x,于是出现矛盾。所以我们应该使0表示同类,1,2分别表示吃与被吃的关系。这样才能推通。 如果之前的话中x与y的关
系还不能被推出,那么合并x与y,并算出x与y的关系;如果之前的话中已知x与y的关系,那么判断当前x与y的关系是否与之前说过的话有冲突,如果有,那
么谎话++,否则不做操作;题目中给的d=2时,x吃x的情况其实可以看做是同一集合当前谎话与之前说过的话的冲突来处理
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int const N=50010;
int f[N];
int rela[N];
int Find(int a)
{
int r=0;
int b=a;
while(b!=f[b])
{
r += rela[b];
b=f[b];
}
while(f[a]!=b)
{
int tmp = f[a];
f[a]=b;
r -= rela[a];
rela[a] += r;
a = tmp;
}
return b;
}
void Union(int x,int y,int r)
{
int fx=Find(x);
int fy=Find(y);
rela[fx]=rela[y]-rela[x]+r;
f[fx]=fy;
}
int main()
{
int m,n;
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
f[i]=i;
rela[i]=0;
}
int k=0;
while(n--)
{
int d,x,y;
scanf("%d%d%d",&d,&x,&y);
if(x>m||y>m) k++;
else if(Find(x)==Find(y))
{
if(((rela[x]-rela[y])%3+3)%3!=d-1) k++;
}
else if(Find(x)!=Find(y))
Union(x,y,d-1);
}
printf("%d\n",k);
return 0;
}
原文:http://www.cnblogs.com/Amidgece/p/5742688.html