• 小希的迷宫


    小希的迷宫

    Description
    上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。 
            

    Input

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

    对于输入的每一组数据,输出仅包括一行。如果该迷宫符合小希的思路,那么输出"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

    思路:

    使用并查集或者DFS判断图中是否有环形成,在函数union_set 里面一旦两个节点父节点一致即形成了环,输出No。满足以下要求输出Yes:

    1.无环

    2.根节点就一个

    初代版本:(这说明循环数组比迭代器快多了)

    #include <iostream>
    #include <cstring>
    #include <set>
    using namespace std;
    
    const int maxn = 1e5+10;
    
    int pre[maxn];
    int vis[maxn];
    bool flag;
    int maxnum;
    void init() {
        for (int i=0; i<maxn; i++) pre[i] = i;
        memset(vis,0,sizeof vis);
        flag = true;
    }
    int find(int x) {
        if (x == pre[x]) return  x;
        return pre[x] = find(pre[x]);
    }
    
    void merge(int a,int b) {
        int ra = find(a);
        int rb = find(b);
        if (ra == rb) 
            flag = false;//形成环
        else 
            pre[ra] = rb;
    }
    
    int main() {
        init();
        int u,v;
        set<int>st;
        while ( scanf("%d%d",&u,&v) ) {
            if ( u == -1 && v == -1 ) return 0;
    
            if ( u == 0 && v == 0 ) {
                int cnt = 0;
                for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
                    if (vis[*it] && pre[*it] == *it) cnt++;
                }
                // for (int i=1; i<=maxnum; i++) 
                //     if (vis[i] && pre[i] == i) cnt++;
                if (flag && cnt<=1)
                    cout<<"Yes"<<endl;
                else 
                    cout<<"No"<<endl;
                init();
                st.clear();
                continue;
            }
            st.insert(u);st.insert(v);
            vis[u] = 1;
            vis[v] = 1;
            if (u != v) merge(u,v);
        }
        return 0;
    }
    View Code

    更新版本:想着每次初始化得循环1e+5次,于是使用了vector初始化,结果速度还慢了。

    #include <iostream>
    #include <cstring>
    #include <set>
    #include <vector>
    using namespace std;
    const int maxn = 1e5+10;
    int pre[maxn];
    bool flag;
    int find(int x) {
        if (x == pre[x]) return  x;
        return pre[x] = find(pre[x]);
    }
    void merge(int a,int b) {
        int ra = find(a);
        int rb = find(b);
        if (ra == rb) 
            flag = false;//形成环
        else 
            pre[ra] = rb;
    }
    
    int main() {
        flag = true;
        int u,v;
        set<int>st;
        vector<int> vec;
        while ( scanf("%d%d",&u,&v) ) {
            //测试数据结束
            if ( u == -1 && v == -1 ) return 0;
            if ( u == 0 && v == 0 ) {
                //初始化pre数组
                for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
                    pre[*it] =*it;
                }
                //合并
                for (vector<int>::iterator vit=vec.begin()  ; vit !=vec.end(); vit++){
                    int u1 = *vit;
                    vit++;
                    int v1 =*vit;
                    if (u1 != v1) merge(u1,v1);
                }
                int cnt = 0;
                //判断联通图的个数
                for (set<int>::iterator it = st.begin(); it != st.end(); it++) {
                    if (pre[*it] == *it) cnt++;
                }
                if (flag && cnt<=1)
                    cout<<"Yes"<<endl;
                else 
                    cout<<"No"<<endl;
                flag = true;
                st.clear();
                vec.clear();
                continue;
            }
            vec.push_back(u);
            vec.push_back(v);
            st.insert(u);
            st.insert(v);
        }
    }
    View Code

     

    因上求缘,果上努力~~~~ 作者:每天卷学习,转载请注明原文链接:https://www.cnblogs.com/BlairGrowing/p/14300396.html

  • 相关阅读:
    HTTP 常见状态码
    SpringMVC 入门
    Maven 整合SSH框架
    SSH 框架整合总结
    Maven 整合SSH框架之pom.xml
    Maven 入门
    WebService 综合案例
    CXF 框架
    jQuery高级
    JavaScript补充:BOM(浏览器对象模型)
  • 原文地址:https://www.cnblogs.com/BlairGrowing/p/14300396.html
Copyright © 2020-2023  润新知