hdu 小希的迷宫
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272
这是一个并查集题,看似很水,其实陷阱也有很多,尤其是有了垃圾数据0 0,- -
注意几个地方:(1)0 0输出Yes;(2),可能不是连通图,所以要判断是否连通,不连通No;(3),可能不是每个点都出现,比如最大点4,只出现了1 2 4,所以要注意标记。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
#define N 100005
int p[N], r[N], v[N];
bool ans[N];
void makeset(int n){
for (int i = 1; i <= n; i++){
p[i] = i;
r[i] = 0;
ans[i] = false;
}
}
int findset(int x){
if (x != p[x])
p[x] = findset(p[x]);
return p[x];
}
void unionset(int x , int y){
x = findset(x);
y = findset(y);
if (r[x] > r[y])p[y] = x;
else {
p[x] = y;
if (r[x] == r[y])r[y]++;
}
}
int main()
{
int a, b;
while (scanf("%d%d", &a, &b) != EOF)
{
if (a == -1 && b == -1)break;
//有垃圾数据0 0
if (!a && !b){
cout<<"Yes"<<endl;
continue;
}
makeset(N - 3);
int m = max(a, b);
bool flag = false;
unionset(a, b);
//标记已经出现
ans[a] = ans[b] = true;
while (scanf("%d%d", &a, &b) && (a || b))
{
//判断是否有环
if (findset(a) == findset(b))
flag = true;
else {
unionset(a, b);
}
m = max(m, max(a, b));
ans[a] = ans[b] = true;
}
//判断根节点是否唯一
int temp = -1;
for (int i = 1; i <= m; i++){
if (ans[i]){
if (temp == -1)temp = findset(i);
else if (temp != findset(i))
{
flag = true;
break;
}
}
}
if (flag)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
return 0;
}
浙公网安备 33010602011771号