中文题。。题意不需解释。。。并查集题目,判断条件显然为所有输入的点都已经访问到并且总集合数为1,同时如果对当前输入的两个点,他们的root必须不一样,因为如果一样即可以从这两个点的任意一个点出发访问到另一个点。。。如上述条件都满足则可以输出Yes,反之输出No。本人此题RE了N次,表示如果OJ显示STACK FLOW就是main()函数里面的数组开多开大了,少用数组即可。。。
代码如下:
# include <iostream>
using namespace std;
const int len = 100100;
int root[len];
int Find(int xx)
{
int x = xx;
while (x != root[x]){x = root[x];}
return x;
}
void Union(int x, int y)
{
int xx = Find(x), yy = Find(y);
if (xx == yy)return ;
if (yy > xx)root[yy] = xx;
else root[xx] = yy;
}
int main()
{
int s1, s2;
int k = 1;
while (EOF != scanf("%d %d", &s1, &s2) &&(s1+s2!=-2)){
int visited[len] = {0};
for (int i = 1; i <= len; i ++){
root[i] = i;
}
if (s1+s2==0){
cout<<"Yes/n";
continue;
}
int check = 0;
int maxx = -1, minn = len;
while (s1|s2){
visited[s1] = visited[s2] = 1;
if (maxx < s1)maxx = s1;
if (minn > s2)minn = s2;
if (maxx < s2)maxx = s2;
if (minn > s1)minn = s1;
if (Find(s1) == Find(s2)){check = 1;}
else
Union(s1, s2);
scanf("%d %d", &s1, &s2);
}
if (check)printf("No/n");
else {
int jud = 0;
for (int i = minn; i <= maxx; i ++){
if (root[i] == i && visited[i]){
jud ++;
}
}
if (jud == 1){
printf("Yes/n");
}
else printf("No/n");
}
}
//system("pause");
return 0;
}