HDU1272 小希的迷宫

//先判断是否能成为一棵树,没有多余的节点
//在判断是否生成环  
//解决第一个问题,直接合并
//解决第二个问题,查找
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;

const int maxn = 100010;

struct Edge{
    int v1, v2;
    Edge(int _v1 = 0, int _v2 = 0):v1(_v1),v2(_v2){}
};

Edge E[maxn];
int cnt;
int parent[maxn];
int Rank[maxn];
int sign[maxn];

void Init(){
    cnt = 0;
    memset(sign, 0, sizeof(sign));
    for(int i = 0; i < maxn ;i++){
        parent[i] = i;
        Rank[i] = 1;
     }
}

int findRoot(int x){
   int tempRoot;
   int root = x;
   while(root != parent[root])
        root = parent[root];
    while(x != root){
        tempRoot = parent[x];
        parent[x] = root;
        x = tempRoot;
    }
      return root;
}

void Union(int x, int y){
    int xRoot = findRoot(x);
    int yRoot = findRoot(y);
    
    if(xRoot == yRoot)
       return ;
    if(Rank[xRoot] < Rank[yRoot])
       parent[xRoot] = yRoot;
    else if(Rank[xRoot] > Rank[yRoot])
       parent[yRoot] = xRoot;
    else {
        parent[xRoot] = parent[yRoot];
        Rank[yRoot] ++;
    }
    
}

void Kruskal(){
    int k = 0;
    for(int i = 0; i < cnt; ++ i){
        if(findRoot(E[i].v1) == findRoot(E[i].v2)){
                printf("NO\n");
                return ;    
        }  
        else {
            Union(E[i].v1,E[i].v2);
        }
    }
    
     for(int i = 0 ; i < cnt; i++ ){
           if(sign[E[i].v1] == 0 && E[i].v1 == parent[E[i].v1]){
                k++;
               sign[E[i].v1] = 1;
           }
        if(sign[E[i].v2] == 0 && E[i].v2 == parent[E[i].v2]){
               k++;
               sign[E[i].v2] = 1;
           }
    }
    if(k==1){
        printf("YES\n"); return ;
    } else {
        printf("NO\n");
        return ;
    }
}

int main(){
    int v1, v2;
    Init();
    while(scanf("%d%d",&v1,&v2)!=EOF){
        if(v1 == -1&&v2 == -1) break;
        if(v1 == 0 && v2 == 0){
           printf("YES\n");
           continue;
       }
       E[cnt++] = Edge(v1,v2);
       while(scanf("%d%d",&v1,&v2)&&v1&&v2){
               E[cnt++] = Edge(v1,v2);
       }
       Kruskal();
       Init();
    }    
    return 0;
}

你可能感兴趣的:(ACM,图论,HDU,kruskal,并查集)