1. 程式人生 > >HDU 小希的迷宮 (簡單並查集)

HDU 小希的迷宮 (簡單並查集)

這裡寫圖片描述
如圖所示,給定n個點,判斷圖中是否有環。

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

Solution

對於兩個點a,b,如果兩個點不同時屬於一個集合則進行unite,直至遇到兩個點都屬於同一個集合會出現環,注意判斷多個圖的情況

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int pre[30010];

void init(int len)
{
    // memset(pre, -1, sizeof(int) * len);
    for (int
i = 0; i <= len; i++) { pre[i] = i; } } int find(int x) { if (pre[x] == x) { return x; } return pre[x] = find(pre[x]); } void join(int i, int j) { int iRoot = find(i); int jRoot = find(j); if (iRoot != jRoot) { pre[jRoot] = iRoot; } } int
main() { int id, lines; while (scanf("%d%d", &id, &lines) && (id || lines)) { init(id); while (lines--) { int num_stu, stu1, pre_stu; scanf("%d", &num_stu); for (int i = 0; i < num_stu; i++) { scanf("%d", &stu1); if (i == 0) { pre_stu = stu1; } join(pre_stu, stu1); pre_stu = stu1; } } int ans = 1; for (int i = 1; i <= id; i++) { if (find(0) == find(i)) { ans++; } } cout << ans << endl; } }