1. 程式人生 > >hdu1272 簡單並查集

hdu1272 簡單並查集

題目連結在這裡

題目大意:

中文題目,自己看吧。

思路分析:

裸的並查集。。。太裸了。只需要注意只輸入0 0的時候輸出Yes

程式碼如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(i, n) for(int i = 0; i < n; ++i)
#define clr(x) memset(x, 0, sizeof(x))
using namespace std;

const int MaxN = 1e5 + 10;
int par[MaxN], r[MaxN];
bool vis[MaxN];
int n, cnt, num_edge;
bool flag;
void init(){
    rep(i, MaxN)    par[i] = i;
    clr(r);
    clr(vis);
    n = cnt = num_edge = 0;
    flag = true;
}

int Find(int x){
    if(x == par[x]) return x;
    return par[x] = Find(par[x]);
}

bool unite(int x, int y){
    x = Find(x);
    y = Find(y);
    if(x == y)  return false;
    if(r[x] < r[y]) par[x] = y;
    else{
        par[y] = x;
        if(r[x] == r[y])    ++r[x];
    }
    return true;
}

int main(){
    ios::sync_with_stdio(false);
    int x, y;
    init();

    while(scanf("%d %d", &x, &y)){
        if(x == -1 && y == -1)  break;
        if(x == 0 && y == 0){
            if(cnt == 0){
                puts("Yes");
            }
            else{
                if(flag && num_edge == cnt - 1) puts("Yes");
                else puts("No");
            }

            init();
            continue;
        }
        ++num_edge;
        if(!vis[x]){
            ++cnt;
            vis[x] = true;
        }
        if(!vis[y]){
            ++cnt;
            vis[y] = true;
        }
        if(!unite(x, y))
            flag = false;
    }
    return 0;
}