0w1

POJ 1182 Food Chain ( Union Find )

1182 -- 食物链
這題解法我覺得很特別,是要維護哪些情報有相互證明的關係,哪些情報有相互排斥的關係,哪些情報沒有關係。這些都可以透過並查集的一些小技巧解決。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 4;
const int MAXK = 1e5 + 5;

int n, k;

struct UnionFind{
    int fa[ MAXN ];
    void init(int p){
        for(int i = 1; i <= p; ++i)
            fa[ i ] = i;
    }
    int find(int x){ return fa[ x ] == x ? x : fa[ x ] = find( fa[ x ] ); }
    bool unite(int x, int y){
        int a = find( x );
        int b = find( y );
        if( a == b ) return false;
        fa[ a ] = b; return true;
    }
} uf;

int getidx(int idx, int type){
    return idx * 3 - type;
}

int main(){
    int ans = 0;
    scanf("%d%d", &n, &k);
    uf.init( n * 3 );
    for(int i = 0; i < k; ++i){
        int op, x, y; scanf("%d%d%d", &op, &x, &y);
        if( x > n || y > n ){
            ++ans;
            continue;
        }
        if( op == 1 ){
            if( uf.find( getidx( x, 0 ) ) == uf.find( getidx( y, 1 ) ) ||
                uf.find( getidx( x, 0 ) ) == uf.find( getidx( y, 2 ) ) ){
                ++ans;
                continue;
            }
            for(int i = 0; i < 3; ++i)
                uf.unite( getidx( x, i ), getidx( y, i ) );
        } else{
            if( uf.find( getidx( x, 0 ) ) == uf.find( getidx( y, 0 ) ) ||
                uf.find( getidx( x, 0 ) ) == uf.find( getidx( y, 2 ) ) ){
                ++ans;
                continue;
            }
            for(int i = 0; i < 3; ++i)
                uf.unite( getidx( x, i ), getidx( y, ( i + 1 ) % 3 ) );
        }
    }
    printf("%d\n", ans);
    return 0;
}