HDU 小希的迷宫 (简单并查集)

来源:互联网 发布:毛孔粗大如何改善知乎 编辑:程序博客网 时间:2024/06/14 08:58

这里写图片描述
如图所示,给定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;    }}