HDU 1272:小希的迷宮 && HDU 1325:Is It A Tree?

HDU 1272:小希的迷宮

判斷圖連通且無環即可。並查集水題,圖連通說明整個集合只有一個代表,

無環即插入的任何x,y。x,y不能屬於同一集合。本題坑點,直接輸入0 0

屬於空圖,也要輸出Yes。

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

const int maxn =100004;
int n,m;
int fa[maxn],vis[maxn];
void initSet() {
    for(int i = 1; i < maxn; i++) {
        fa[i] = i;
    }
}
int findSet(int x) {
    int temp = x;
    while(x!=fa[x]) {
        x = fa[x];
    }
    while(temp!=fa[temp]) {
        temp = fa[temp];
        fa[temp] = x;
    }
    return x;
}
void unionSet(int x,int y) {
    fa[x] = y;
}
int main() {
    int x,y,fx,fy;
    while(~scanf("%d%d",&x,&y)) {
        if(x==-1 && y==-1) {
            break;
        }
        if(x==0 && y==0) {
            printf("Yes\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        initSet();
        bool flag = true; //代表無環
        vis[x] = 1;
        vis[y] = 1;
        fx = findSet(x);
        fy = findSet(y);
        if(fx==fy) {
            flag = false;
        }
        else {
            unionSet(fx,fy);
        }
        while(true) {
            scanf("%d%d",&x,&y);
            if(x==0 && y==0) break;
            vis[x] = 1;
            vis[y] = 1;
            fx = findSet(x);
            fy = findSet(y);
            if(fx == fy){
                flag = false;
            }
            else {
                unionSet(fx,fy);
            }
        }
        int cnt = 0;
        for(int i = 1; i < maxn; i++) {
            if(vis[i]==1) {
                if(fa[i]==i) {
                    cnt++;
                }
            }
        }
        if(cnt==1 && flag) {
            printf("Yes\n");
        }
        else {
            printf("No\n");
        }
    }
    return 0;
}

HDU 1235 Is It A Tree

一顆樹不能有環,且連通塊數爲1,和上題相同,但是並查集不會考慮邊的有向性,所以

需要多加判斷是否存在一個點有多個父親,這也是樹這種數據結構所不允許的。

#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

const int maxn =100005;
int n,m;
int fa[maxn],vis[maxn],in[maxn];
void initSet() {
    for(int i = 1; i < maxn; i++) {
        fa[i] = i;
    }
}
int findSet(int x) {
    int temp = x;
    while(x!=fa[x]) {
        x = fa[x];
    }
    while(temp!=fa[temp]) {
        temp = fa[temp];
        fa[temp] = x;
    }
    return x;
}
void unionSet(int x,int y) {
    fa[y] = x;
}
int main() {
    int x,y,fx,fy,t=0;
    while(~scanf("%d%d",&x,&y)) {
        if(x<0 && y<0) {
            break;
        }
        if(x==0 && y==0) {
            printf("Case %d is a tree.\n",++t);
            continue;
        }
        memset(vis,0,sizeof(vis));
        memset(in,0,sizeof(in));
        initSet();
        bool flag = true; //代表無環
        vis[x] = 1;
        vis[y] = 1;
        in[y]++;
        fx = findSet(x);
        fy = findSet(y);
        if(fx==fy) {
            flag = false;
        }
        else {
            unionSet(fx,fy);
        }
        while(true) {
            scanf("%d%d",&x,&y);
            if(x==0 && y==0) break;
            vis[x] = 1;
            vis[y] = 1;
            in[y]++;
            //一個點有兩個父親。
            if(in[y]>1) {
                flag = false;
            }
            fx = findSet(x);
            fy = findSet(y);
            if(fx == fy){
                flag = false;
            }
            else {
                unionSet(fx,fy);
            }
        }
        int cnt = 0;
        for(int i = 1; i < maxn; i++) {
            if(vis[i]==1) {
                if(fa[i]==i) {
                    cnt++;
                }
            }
        }
        if(cnt==1 && flag) {
            printf("Case %d is a tree.\n",++t);
        }
        else {
            printf("Case %d is not a tree.\n",++t);
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章