HDU 小希的迷宮 (簡單並查集)
阿新 • • 發佈:2019-01-22
如圖所示,給定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;
}
}