这题只要判断一下有没有环,并且要保证只有一个集合。
还有一个坑就是:x==0 y==0, 输出yes。因为没有点,也是符合要求的。
我这里没有用压缩路径,据说这题压缩路径会爆栈,如果爆栈的话,find里面换用循环的方式写就行了。
附上ac代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<set>
using namespace std;
const int Max = 1e5+5;
int pre[Max];
void init()
{
for(int i=0;i<Max;i++)
{
pre[i]=i;
}
}
int find(int x)
{
int tmp = x;
while(x!=pre[x])
{
x=pre[x];
}
pre[tmp]=x;
return x;
}
void Union(int x,int y)
{
int rootx = find(x);
int rooty = find(y);
if(rootx!=rooty)
{
pre[rootx]=rooty;
}
}
int main()
{
int x,y;
int flag=1;
set<int> st;
while(1)
{
flag=1;
int flag_0=0; //判断这一组中是否开始就 0 0
int cnt=0;
init();
if(x==-1 && y==-1) break;
while(scanf("%d%d",&x,&y))
{
if(cnt==0 && x==0 && y==0)
{
flag_0=1;
break;
}
cnt++;
st.insert(x);
st.insert(y);
if(x==y) break;
int rootx = find(x);
int rooty = find(y);
if(rootx == rooty)
{
flag=0;
}
else
{
Union(x,y);
}
}
if(x==-1 && y==-1) continue;
//cout<<"len "<<st.size()<<endl;
if(flag && st.size()==cnt+1 || flag_0 ==1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
st.clear();
//printf("\n");
getchar();
}
return 0;
}