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;
}

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