注意:并不是所有的节点都在迷宫中出现了,我们只需要保证出现的节点构成了一个并查集就可以了。
判断是否有环的标志:每次给出的边(a–b)一点不是同一个父亲,否则则构成了环。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100007;
int Max;
int fa[maxn];
bool v[maxn];
// int find(int x)
// {
// if(x==fa[x])
// return x;
// else
// return fa[x] = find(fa[x]);//压缩路径
// }
int find(int x)//压缩路径的非递归写法,数量量较大时才用
{
int r = x;//储存临时变量
while(fa[r]!=r)r = fa[r];//找到父节点
int i = x, j;
while(i!=r)
{
j = fa[i];//储存临时变量
fa[i] = r;//把路径上的指向父节点
i = j;
}
return r;//返回父节点
}
int main()
{
freopen("11.txt", "r", stdin);
int x, y;
bool flag = true;
for (int i = 0;i<=maxn;i++)
fa[i] = i;
while (scanf("%d%d", &x, &y)!=EOF)
{
if (x == -1 && y == -1)
break;
if (x == 0 && y == 0) //需要输出并更新
{
int cnt = 0;
for (int i = 1;i<=Max;i++)
if(fa[i]==i&&v[i])
cnt++;//只能有一个爹
if (flag&&cnt<=1)
cout << "Yes" << endl;
else
cout << "No" << endl;
//初始化数据为下一次作准备
for (int i = 0;i<=maxn;i++)
fa[i] = i;
memset(v, 0, sizeof(v));
flag = 1;
}
else
{
int a = find(x), b = find(y);
Max = max(a, max(Max, b));
if(a==b) flag = 0;
else fa[b] = a , v[x]=v[y]=1 ;//标记访问节点,并且将 a,b 相连。
}
}
return 0;
}