hdu1272 小希的迷宫

 昨天挂了场比赛,发现好久没写并查集都生疏了,今天就又拿了道之前的老题目来做了下, 题目不难,要注意的地方都加了注释,如果有错误欢迎大牛指正

#include <iostream>
using namespace std;
const int size = 100100;
int root[size];
int find(int x)
{
    int t = x;
    while (t != root[t]){
          t = root[t];
    }   
    return t;
}

void unio(int x, int y)
{
     int xx = find(x), yy = find(y);
     if (xx == yy)return ;
     if (yy > xx)root[yy] = xx;
     else root[xx] = yy;    
}

bool visited[100100];
int main()
{
    bool flag = false;
    while (!flag){
         
          int a, b;
          memset(visited, false, sizeof(visited));
          int maxx = -1, minn = INT_MAX;
          int jud = true;
          int jud0 = true;
          for (int i = 1; i < size; i ++)root[i] = i;
          int nc = 0;
          while (scanf("%d%d", &a, &b)){
                if (a == 0  && b == 0){if (!nc)jud0=false;break;}
                if (a == -1 && b == -1){flag = true; break;}
                if (find(a) == find(b))jud = false;//如果之前存在a可抵达root[a]、存在b可抵达root[b]那么如果 find(a) == find(b)在归并之前就相等,则必存在另外一条路径可由a->b->root[a](或root[b])
                else//如果有上述情况出现则可直接判断"No"
                    unio(a, b);
                if (maxx < a)maxx = a;
                if (maxx < b)maxx = b;
                if (minn > a)minn = a;
                if (minn > b)minn = b;
                visited[a] = visited[b] = true;
                nc ++;
          }
          if (!jud0){printf("Yes\n");continue;}//这个地方不知道为什么第一次输入0 0(地图不存在)要判断Yes,不知道是不是数据问题
          if (flag)break;
          for (int i = minn; i <= maxx ; i ++){
              root[i] = find(i);
          }
          int k = 0;
          for (int i = minn; i <= maxx; i ++){
              if (root[i] == i && visited[i]){//这里判断是不是存在不连通的子图
                 k ++;           
              }  
          }
          if (k != 1)jud = false;
          jud?printf("Yes\n"):printf("No\n");
    }   
    return 0;   
}

你可能感兴趣的:(hdu1272 小希的迷宫)