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

    题意:给定两个数,这两个数之间连有一条通路,以0,0作为一组数据的结束,以-1,-1作为整体结束,让你判断是否每两个点之间只有一条通路。

    思路:每两个点之间要连通(即有关系),由此想到并查集,利用并查集找祖宗(根节点)的方式合并这些给定的点,而且,要满足只有一条通路,那么这集合中不能出现环,(一旦出现环就意味着出现有两点之间出现了多条通路,自己画画看),可以用一个标记flag来判断是否出现环路(出现环路的话就是找祖宗(根节点)时两个点有同一个祖宗(根节点))。

    此题还有一个坑点,如果出现两个或以上集合时,一定有两个点不连通,此时是不满足题意的,可以用一个数组vis标记有那些点出现过,然后看看是否出现过的所有点都只有唯一的祖宗。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=100006;
     6 bool flag;
     7 int f[maxn];
     8 int vis[maxn];
     9 int find(int v)//并查集寻找根节点 
    10 {
    11     if(f[v]==v)
    12     return v;
    13     else
    14     return find(f[v]);
    15 }
    16 void merge(int u,int v)//合并 
    17 {
    18     int t1=find(u);
    19     int t2=find(v);
    20     if(t1!=t2)//两个点的根节点不同,意味着两点属于不同集合 
    21     {
    22         f[t2]=t1;
    23     }
    24     else//如果两个点已经在同一个集合(有同一个根节点),就说明已经有一条路将两点相连,再有就不符合题意了 
    25     {
    26         flag=false;
    27     }
    28 }
    29 int main()
    30 {
    31     int x,y;
    32     while(~scanf("%d%d",&x,&y))//题目要求多组输入,先输入两个数是为了对应下面的特判 
    33     {
    34         if(x==0&&y==0)//本题的特判,如果只输入了0,0,也是符合要求的,试出来的... 
    35         {
    36             printf("Yes
    ");
    37             continue;//需要继续输入下一组数据 
    38         }
    39         for(int i=0;i<=maxn;i++)//每次输入新的一组数据时都要初始化 
    40         {
    41             f[i]=i;//并查集初始化 
    42             vis[i]=0;//标记出现过的点 
    43         }
    44         if(x==-1&&y==-1)//输入-1,-1结束 
    45         break;
    46         merge(x,y);//合并两个点入一个集合 
    47         flag=true;//这是判断是否有环路出现的标志 
    48         vis[x]=1;
    49         vis[y]=1;//将先输入的两点先标记 
    50         while(scanf("%d%d",&x,&y),x,y)
    51         {
    52             merge(x,y);//合并 
    53             vis[x]=1;//标记 
    54             vis[y]=1;
    55         }
    56         if(!flag)
    57         {
    58             printf("No
    ");//有环路,则不符合要求 
    59             continue;//继续下一组数据 
    60         }
    61         else//在没有环路的前提下再判断其他情况 
    62         {
    63             int cnt=0;//判断有几个集合 
    64             for(int i=0;i<=maxn;i++)
    65             {
    66                 if(vis[i]&&f[i]==i)//在已经(给出)出现的点中有几个根节点是自己就有几个集合 
    67                 cnt++;
    68             }
    69             if(cnt==1)
    70             {
    71                 printf("Yes
    ");//当只有一个集合时,符合题意 
    72             }
    73             else
    74             {
    75                 printf("No
    ");//否则不符 
    76             }
    77         }
    78     }
    79 }
  • 相关阅读:
    Caffe--solver.prototxt配置文件 参数设置及含义
    关于KMP算法理解(快速字符串匹配)
    Lintcode--004(最小子串覆盖)
    Lintcode--003(乱序字符串)
    Lintcode--002(两个字符串是变位词)
    Lintcode--001(比较字符串)
    闭包的应用实例
    JavaScript完整性检查
    null和undefined相等比较
    JavaScript逻辑运算符(操作数运算符)
  • 原文地址:https://www.cnblogs.com/theshorekind/p/12675419.html
Copyright © 2011-2022 走看看