poj1182 food chain (the kind of disjoint-set)

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

 

Guess you like

Origin www.cnblogs.com/sweetlittlebaby/p/12654817.html