Links: http://poj.org/problem?id=1182
Disjoint-set to maintain a relative relationship;
And to solve the enemy's enemy is my friend (that is circularly symmetric) of this relationship, with the kind of disjoint-set to solve
If a set of three or more, as long as each set are equivalent, and the relationship between each set are equivalent, maintenance can be performed with disjoint-set type.
Meaning of the questions:
Under observation, (Common practice disjoint-set) can be found in a set of three disjoint-set type to solve: a triple maintenance can be disjoint-set size, with i + n i represents the prey, and i + 2n i represents a natural enemy.
Weights (weighted disjoint-set approach) Weighted disjoint-set of two animals indicates a relative relationship on the food chain A-> B = 0 (the same), A-> B = 1 (A eat B), A- > B = 2 (B eat A);
Note three points:
1, when the compression path, how to update the value value:
A-> B is 1, B-> C to 1, how seeking A-> C? Obviously eating A B, B eat C, the C should eat A, A-> C should be 2;
A-> B is 2, B-> C 2, how to find A-> C? Obviously eating B A, C eat B, then A should eat C, A-> C be 1;
A-> B is 0, B-> C to 1, how seeking A-> C? Obviously A, B grade, then A should eat C, A-> C be 1;
Observation can be found Law: A-> C = (A-> B + B-> C)% 3;
2, when the interval merge, how to update the value value:
Common the combined weighted to add modulo, va [fx] = (s + va [y] -va [x])% 3;
3, how to determine whether conflicts
To prevent the negative impact A-> B = (A-> C - B-> C + 3)% 3, the A-> B and the value given in question can be determined
Because the problem only in cases 1 and 2, so --d;
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxx 1010
#define maxn 50010
int fa[maxn],va[maxn];
int Find(int x)
{
if(x!=fa[x])
{
int t=fa[x];
fa[x]=Find(fa[x]);
va[x]=(va[x]+va[t])%3;//合并权值
}
return fa[x];
}
void Union(int x,int y,int s)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
fa[fx]=fy;
va[fx]=s+va[y]-va[x];
}
}
int main()
{
for(int i=0; i<=maxn-10; i++)
fa[i]=i;
int n,k;
cin>>n>>k;
int ans=0;
while(k--)
{
int d,x,y;
cin>>d>>x>>y;
if((x==y&&d==2)||x>n||y>n)
ans++;
else
{
int fx=Find(x),fy=Find(y);
if(fx==fy)
{
if((d-1)!=(va[x]-va[y]+3)%3)
ans++;
}
else
{
fa[fx]=fy;
va[fx]=((d-1)+va[y]-va[x])%3;
}
}
}
cout<<ans<<endl;
return 0;}