hdu1272 小希的迷宮--並查集
阿新 • • 發佈:2019-01-08
一:原題內容
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
二:分析理解
1.檢測是否存在環,如果存在,則輸出No
2.檢測是否連通,連通就是任意兩點可達,如果不連通,也就是存在大於1的rootNum,輸出No
三:AC程式碼
#include<iostream> #include<string.h> #include<algorithm> using namespace std; int pre[100001]; int vis[100001]; bool flag;//標記是否存在環 int rootNum;//標記源點個數,檢測是否連通 int x, y; int Find(int x) { return (x != pre[x]) ? Find(pre[x]) : x; } void Union(int x, int y) { int x_root = Find(x); int y_root = Find(y); if (x_root != y_root) pre[y_root] = x_root; else flag = 0;//為環 } int main() { while (scanf("%d%d", &x, &y)) { if (x == -1 && y == -1) break; if (x == 0 && y == 0)//這點挺坑的,容易忘記!!! { printf("Yes\n"); continue; } memset(vis, 0, sizeof(vis)); for (int i = 1; i < 100001; i++) pre[i] = i; flag = 1; rootNum = 0; vis[x] = vis[y] = 1; Union(x, y); while (scanf("%d%d", &x, &y) && (x || y)) { vis[x] = vis[y] = 1; Union(x, y); } for (int i = 1; i < 100001; i++) { if (vis[i]) { if (i == pre[i]) rootNum++; if (rootNum >= 2 || flag == false) break; } } if (rootNum == 1 && flag) printf("Yes\n"); else printf("No\n"); } return 0; }