いろいろがんばりたいブログ

情報科学科の人がいろいろ書きます。

POJ 1182 食物链

蟻本のUnion-Findのやつ。
cin,coutをつかってたらTLEした。
(ios::sync_with_stdio(false);しても)

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <utility>
#include <numeric>
#include <algorithm>
#include <functional>
#include <cctype>
#include <complex>
#include <string>
#include <sstream>

using namespace std;

#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(),c.rend()
#define rep(i,n) for(int i=0;i<(n);i++)
#define tr(it,container) for(typeof(container.begin()) it = container.begin(); \
                                                  it != container.end(); ++it)
#define mp(a,b) make_pair((a),(b))
#define eq ==

class UnionFind{
public:
    vector<int> par; // 親
    vector<int> rank; // 木の深さ
    UnionFind(int n){
        par = vector<int>(n);
        rep(i,n) par[i] = i;
        rank = vector<int>(n);
    }
    // 親を探す
    int root(int x){
        if(par[x] == x){
            return x;
        }else{
            // 縮約?
            return par[x] = root(par[x]);
        }
    }
    // x,yの含まれる集合を併合
    void unite(int x,int y){
        x = root(x);
        y = root(y);
        if(x==y) return;
        if(rank[x] < rank[y]){
            par[x] = y;
        }else{
            par[y] = x;
            if(rank[x] == rank[y]) rank[x]++;
        }
    }

    bool same(int x,int y){
        return root(x) == root(y);
    }
};

int main(){
    int N,K;
    scanf("%d %d",&N,&K);
    UnionFind uf(3*N);
    int ret = 0;
    for(int index=0;index<K;index++){
        int t,x,y;
        scanf("%d %d %d",&t,&x,&y);
        x--;y--;
        if(x < 0 or N <= x or y < 0 or N <= y){
            ret++;
            continue;
        }
        if(t==1){
            if(uf.same(x,y+N) or uf.same(x,y+2*N)){
                ret++;
            }else{
                uf.unite(x,y);
                uf.unite(x+N,y+N);
                uf.unite(x+2*N,y+2*N);
            }
        }else{
            if(uf.same(x,y) or uf.same(x,y+2*N)){
                ret++;
            }else{
                uf.unite(x,y+N);
                uf.unite(x+N,y+2*N);
                uf.unite(x+2*N,y);
            }
        }
    }
    printf("%d\n",ret);

    return 0;
}