初看题的时候, 我想到的是DFS, 但我觉得肯定要超时的, 我搜了个解题报告, 发现用并查集做的, 深受启发,于是用并查集做了。第一次提交WR,修改了一下,提交结果Runtime Error (STACK_OVERFLOW) ,学到给栈置大小#pragma comment(linker, "/STACK:102400000,102400000"), 再次提交WR, ……没有判断迷宫是否连通;再次修改后终于AC了
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
int parent[100001];
int visited[100001];
void Make(int n)
{
for(int i=1; i<=n; i++)
parent[i]=i;
}
int Find(int a)
{
return parent[a]==a?parent[a]:parent[a]=Find(parent[a]);
}
void Union(int a, int b)
{
parent[a]=b;
}
int main()
{
int a, b, x, y, min=0, max=0;
int flag, temp, i;
while( scanf("%d %d", &a, &b) && (a+b)!=-2)
{
if( a+b==0 ) printf("Yes\n");
else
{
memset(visited+min, 0, max-min+1);
flag=1;min=200000;max=0;
Make(100000);
do{
min=min<(a<b?a:b)?min:(a<b?a:b);
max=max>(a>b?a:b)?max:(a>b?a:b);
visited[a]=1; visited[b]=1;//标记此点存在
x=Find(a);y=Find(b);
if( x==y ) flag=0;
else Union(x, y);
}while( scanf("%d %d", &a, &b) && (a+b)!=0 );
if(flag) //没有回路时, 判断迷宫是否连通
{
temp=Find(min);
for(i=min+1; i<=max; i++)
{
if(visited[i] && Find(i)!=temp)
{
flag=0; break;
}
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
}