Hdu1272 小希的迷宫 【并查集】

http://acm.hdu.edu.cn/showproblem.php?pid=1272

题目大意:判断给定的图是否是一棵树。

1、判断所有点是否都连通

2、每次合并两个点的是否判断这两个点是否已经是在一个集合中了,如果是,那么接下来就不用判断了,因为已经构成了环的条件,已经不可能成为一颗树了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
const int N = 100001;
int f[N];
bool cc[N];
int flag;
int x , y;
void init() {
    for(int i=0;i<N;i++) f[i] = i , cc[i] = 0;
}
int find(int x) {
    return x == f[x] ? x : f[x] = find(f[x]);
}
int main() {
    int ok = 1;
    init();
    while(~scanf("%d%d",&x,&y)) {
        if(x == -1 && y == -1) break;
        if(x == 0 && y == 0) {
            if(ok) {
                for(int i=1;i<N;i++) if(cc[i] && find(i) != flag) {
                    ok = 0;
                    break;
                }
            }
            puts(ok ? "Yes" : "No");
            init();
            ok = 1;
            continue;
        }
        if(ok) {
            cc[x] = cc[y] = 1;
            int a = find(x) , b = find(y);
            if(a == b) {
                ok = 0;
            }
            else {
                flag = f[a] = f[b] = f[x] = f[y] = min(a , b);
            }
        }
    }
    return 0;
}

 

posted @ 2013-03-30 02:29  aiiYuu  阅读(123)  评论(0)    收藏  举报