小希的迷宮
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 47105 Accepted Submission(s): 14642
整個文件以兩個-1結尾。
No
思路:判斷兩種情況 1.是否環路2.是否連通
注意直接出入0 0的時候
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 200005
using namespace std;
int fa[N],flag[N],vis[N];
int find(int x) //找到父節點
{
int a=x;
while(x!=fa[x])
{
x=fa[x];
}
while(a!=fa[a]) //壓縮路徑,可以省略,可能會超時
{
int z=a;
a=fa[a];
fa[z]=x;
}
return x;
}
int Union(int a,int b) //合併節點
{
int faa=find(a);
int fab=find(b);
if(faa!=fab)
{
fa[faa]=fab;
return 1;
}
else
return -1;
}
void init(int n) //初始化
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
}
int main()
{
int a,b;
while(1)
{
int p=1,mark=1,ans=0;
memset(flag,0,sizeof(flag));
memset(vis,0,sizeof(vis));
init(N);
scanf("%d %d",&a,&b);
if(a==-1&&b==-1) break;
else if(!a&&!b){printf("Yes\n");continue;}
else
{
vis[a]=1;
vis[b]=1;
p=Union(a,b);
//while(~scanf("%d %d",&a,&b))
while(1)
{
scanf("%d %d",&a,&b);
if(a==0&&b==0) break;
vis[a]=1;
vis[b]=1;
p=Union(a,b);
if(p==-1)
{
mark=0;
}
}
if(mark==0) //mark==0 表示環路
{
printf("No\n");
}
else //不環路的情況下,是否連通
{
for(int i=1;i<N;i++)
{
if(vis[i]==0) continue;
int x=find(i);
flag[x]=1;
}
for(int i=1;i<N;i++)
{
if(vis[i]==1)
{
if(flag[i]==1)
ans++;
}
}
if(ans==1) //ans==1時 表示連通
printf("Yes\n");
else
printf("No\n");
}
}
}
}