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

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1272

    题目

    小希的迷宫

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 63799    Accepted Submission(s): 20016


    Problem 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
     
    Author
    Gardon
     
    解题思路:并查集入门题,是道水题,但是WA了贼多次。一开始想不用并查集做,但是感觉怎么做都不怎么好做。
     
    正确做法当然是用并查集了,当输入的两个数,先判断两个数的根是否相同,相同说明在同一个集合,如果再合并肯定就形成环了。肯定不可以。
    如果没有环的话,就只有判断所有的点是否连通,直接判断边的数目是否等于点的数目减一就好了。
     
    这题最坑的地方就是开始直接输入0 0是可以的。我在这WA了好多次啊。。。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #include<cstring>
     5 using namespace std;
     6 int par[100005],Rank[100005];
     7 set<int> se;   //方便记录点的个数,不会重复 
     8 int flag;
     9 
    10 void init(int x)
    11 {
    12     for(int i=1;i<=x;i++)
    13     {
    14         par[i]=i;
    15         Rank[i]=0;
    16     }
    17 }
    18 
    19 int find(int x)
    20 {
    21     if(par[x]==x)
    22         return x;
    23     par[x]=find(par[x]);
    24     return par[x];
    25 }
    26 
    27 void unite(int x,int y)
    28 {
    29     int fx=find(x);
    30     int fy=find(y);
    31     if(fx==fy)
    32     {
    33         flag=1;  //形成了环,肯定不行 
    34         return;
    35     }
    36     if(Rank[fx]<Rank[fy])
    37         par[fx]=fy;
    38     else
    39     {
    40         par[fy]=fx;
    41         if(Rank[fx]==Rank[fy]) Rank[fx]++;
    42     }
    43 }
    44 
    45 bool same(int x,int y)
    46 {
    47     return find(x)==find(y);
    48 }
    49 
    50 int main()
    51 {
    52     int n,m,edge=0; //edge记录边的数目 
    53     flag=0;
    54     init(100000);
    55     while(cin>>n>>m&&(n!=-1||m!=-1))
    56     {
    57         if(n==0&&m==0)
    58         {
    59             if(se.size()==0)  //注意 
    60             {
    61                 cout<<"Yes"<<endl;
    62                 continue;
    63             }
    64             if(edge!=se.size()-1) flag=1;
    65             if(flag) cout<<"No"<<endl;
    66             else cout<<"Yes"<<endl;
    67             flag=0;
    68             edge=0;
    69             se.clear();
    70             init(100000);
    71             continue;
    72          }
    73          edge++;
    74         se.insert(n);
    75         se.insert(m);
    76         unite(n,m);
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    Android Studio 中关于NDK编译及jni header生成的问题
    为YAESU FT-817ND 增加频谱功能
    Nagios 安装配置
    ubuntu 13.10 Ralink RT3290 无线与蓝牙4.0的驱动安装
    golang全文搜索--使用sphinx
    GNU Radio 之 rtl-sdr
    OsmocomBB && Motorora C118
    OsmocomBB 编译安装
    Go 若干技巧
    Docker内核知识
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/9449033.html
Copyright © 2011-2022 走看看