zoukankan      html  css  js  c++  java
  • HDU 1272 小希的迷宫 (并查集)

    小希的迷宫

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/123393#problem/L

    Description

    我们的小伙伴Bingo身为大二学长,他乐于助人,同学们问他问题他都耐心的一一回答,但是却有一道题难住了他。我们快来看看到底是什么题吧!这是一个迷宫,首先所有的通道都是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,而且任意两个房间有且仅有一条路径可以相通(除非走了回头路)。现在把设计图给了Bingo,让Bingo帮忙判断设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。

    Input

    输入包含多组数据,每组数据是一个以0 0结尾的整数对列表,表示了一条通道连接的两个房间的编号。房间的编号至少为1,且不超过100000。每两组数据之间有一个空行。
    整个文件以两个-1结尾。

    Output

    对于输入的每一组数据,输出仅包括一行。如果该迷宫符合思路,那么Bingo输出"Yes",否则输出"No"。

    Sample Input

    6 8 5 3 5 2 6 4
    5 6 0 0
    8 1 7 3 6 2 8 9 7 5
    7 4 7 8 7 6 0 0
    3 8 6 8 6 4
    5 3 5 6 5 2 0 0
    -1 -1

    Sample Output

    Yes
    Yes
    No


    ##题意: 判断给出的图是否是联通无环图.
    ##题解: 首先很容易想到用并查集来判断是否有出现环:若新边的两个端点在同一集合则出现环. 一开始没有仔细看题,直接写了并查集就交上去了,但是这个题应该还需要判断是否是联通的,所以要再遍历看所有点是否都在同一集合.
    这个错误警醒了我:在做专题训练的时候,不能先入为主直接往正在训练的算法上想,而是应该多考虑如何正确分析题目才能想到用这种算法,除了这种算法以外还需要运用什么.

    ##代码: ``` cpp #include #include #include #include #include #include #include #include #include #define LL long long #define eps 1e-8 #define maxn 101000 #define mod 100000007 #define inf 0x3f3f3f3f #define IN freopen("in.txt","r",stdin); using namespace std;

    int fa[maxn];
    int _rank[maxn];
    bool vis[maxn];

    void init_set() {
    for(int i=0; i<maxn; i++) {
    fa[i] = i;
    _rank[i] = 0;
    }
    }

    int find_set(int x) {
    return fa[x] = (x==fa[x]? x:find_set(fa[x]));
    }

    void unit_set(int x, int y) {
    vis[x] = vis[y] = 1;
    x = find_set(x);
    y = find_set(y);
    if(_rank[x] < _rank[y]) swap(x, y);
    fa[y] = x;
    if(_rank[x] == _rank[y]) _rank[x]++;
    }

    int main(int argc, char const *argv[])
    {
    //IN;

    int x, y, ans = 1;
    init_set();
    memset(vis, 0, sizeof(vis));
    while(scanf("%d %d", &x, &y) != EOF && (x!=-1||y!=-1))
    {
        if(!x && !y) {
            int last = -1;
            for(int i=0; i<maxn; i++) {
                if(!vis[i]) continue;
                if(last == -1) last = find_set(i);
                if(last != find_set(i)) {
                    ans = 0; break;
                }
            }
            if(ans) puts("Yes");
            else puts("No");
            ans = 1;
            init_set();
            memset(vis, 0, sizeof(vis));
            continue;
        }
    
        if(find_set(x) == find_set(y)) ans = 0;
        else unit_set(x, y);
    }
    
    return 0;
    

    }

  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5709544.html
Copyright © 2011-2022 走看看