• G


    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    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
     
     
     
    数据结构基础题:运用并查集来检查两个点之间是否有两条以上的路,这里特别要注意的是有可能”存在两个集合“,因此我是最后用一个vis[],和ans以及判断是否father[i]==i
    来计算集合的个数(ans).
     
     1 #include<cstdio>
     2 #include<string.h>
     3 using namespace std;
     4 //int rank[100010];
     5 int father[100010];
     6 int max1=0;
     7 int vis[100010];
     8 int find(int x)
     9 {
    10     if(x!=father[x])
    11         father[x]=find(father[x]);
    12     return father[x];
    13 }
    14 bool Union(int x,int y)
    15 {
    16     int x1=find(x),y1=find(y);
    17     if(x1!=y1)
    18     {
    19         father[y1]=x1;
    20         return true;
    21         //rank[x]+=rank[y];
    22         //if(max1<rank[x]) max1=rank[x];
    23         //return;
    24     }
    25     return false;
    26 }
    27 int main()
    28 {
    29     int a,b;
    30     while(scanf("%d %d",&a,&b)!=EOF&&a!=-1&&b!=-1)
    31     {
    32        for(int i=1;i<=100010;i++)
    33            father[i]=i;
    34        if(a==0&&b==0){printf("Yes
    ");continue;} //注意continue!!!
    35        int min=100000000;
    36        int max=0;
    37        int flag=1;
    38        memset(vis,0,sizeof(vis));
    39        while(a||b)
    40         {
    41             if(a>max) max=a;
    42             if(b>max) max=b;
    43             if(a<min) min=a;
    44             if(b<min) min=b;
    45             vis[a]=1;
    46             vis[b]=1;
    47             if(!Union(a,b)) flag=0;
    48             scanf("%d %d",&a,&b);
    49         }
    50         if(flag==0) printf("No
    ");
    51         else{
    52             int ans=0;
    53             for(int i=min;i<=max;i++)
    54                if(vis[i]&&father[i]==i)
    55                    ans++;
    56             if(ans==1) printf("Yes
    ");
    57             else printf("No
    ");
    58         }
    59 
    60     }
    61     return 0;
    62 }

     换了一个小思路

     1 #include<cstdio>
     2 #include<string.h>
     3 using namespace std;
     4 //int rank[100010];
     5 int father[100010];
     6 int rank[100010];
     7 int max1=0;
     8 //int vis[100010];
     9 int find(int x)
    10 {
    11     if(x!=father[x])
    12         father[x]=find(father[x]);
    13     return father[x];
    14 }
    15 bool Union(int x,int y)
    16 {
    17     int x1=find(x),y1=find(y);
    18     if(x1!=y1)
    19     {
    20         father[y1]=x1;
    21 
    22         rank[x1]+=rank[y1];//记录深度
    23         if(max1<rank[x1]) max1=rank[x1];
    24         return true;
    25         //rank[x]+=rank[y];
    26         //if(max1<rank[x]) max1=rank[x];
    27         //return;
    28     }
    29     return false;
    30 }
    31 int main()
    32 {
    33     int a,b;
    34     while(scanf("%d %d",&a,&b)!=EOF&&a!=-1&&b!=-1)
    35     {
    36        for(int i=1;i<=100010;i++)
    37        {
    38            father[i]=i;rank[i]=1;
    39        }
    40 
    41        if(a==0&&b==0){printf("Yes
    ");continue;}
    42        int flag=1;
    43        //memset(vis,0,sizeof(vis));
    44        int ans=0;
    45        while(a||b)
    46         {
    47             ans=ans+1;//这是记录输入的边的条数
    48             if(!Union(a,b)) flag=0;
    49             scanf("%d %d",&a,&b);
    50         }
    51        // printf("%d %d
    ",ans,max1);
    52         if(flag==0) printf("No
    ");
    53         else if(max1-1==ans) printf("Yes
    ");
    54         else printf("No
    ");
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    DataGridView 控件和 DataGrid 控件之间的区别
    winform 如何创建mdi属性IsMdiContainer=true
    窗体分为左右两部分,要求在左边栏点击按钮时,右边动态加载窗体
    OLEDBConnection 和SQLConnection 有什么区别
    成为一个顶级设计师的八大秘诀
    青春追梦
    四维领导力:明道、取势、优术、树人
    走好青春
    再贺开业
    骑车在暴雨中有感
  • 原文地址:https://www.cnblogs.com/angledamon/p/3902793.html
Copyright © 2020-2023  润新知