输入:
6 8 5 3 5 2 6 4
5 6 0 08 1 7 3 6 2 8 9 7 5
7 4 7 8 7 6 0 03 8 6 8 6 4
5 3 5 6 5 2 0 0-1 -1
输出:
Yes
Yes
No
题意:就像图上的,从1到2只能有一条路径。
思路:一眼并查集,查找输入的两个房间的祖宗(抽象),如果相同就不是只有一条路径,最后是所有的房间是只有一个祖宗,然后判断一下这两种情况就OK辣。
代码:
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
const ll N=1e5+1;
int pre[N];
int n,m;
ll find(int x)//查找祖宗的函数
{
if(x==pre[x])return x;
return pre[x]=find(pre[x]);
}
void join(int x,int y)//合并两个集合
{
int a=find(x);
int b=find(y);
if(a!=b)pre[b]=a;
}
int main()
{
while(1)
{
int fl=0,as=0,q=0;
while(~scanf("%d %d",&n,&m)&&n&&m)
{
if(n==-1&&m==-1)return 0;
//这个地方因为我们需要的是n房间和m房间,不能对所有初始化
if(!pre[n])pre[n]=n;
if(!pre[m])pre[m]=m;
int a=find(n);
int b=find(m);
if(a==b)fl=1;
else join(a,b);//如果祖先不一样就合并,比免之后数据出错
q++;
}
for(int i=1;i<=N;i++)
{
if(pre[i]==i)as++;//看最后有几个祖宗
}
if(fl==1||as>1)printf("No\n");
else printf("Yes\n");
memset(pre,0,sizeof(pre));
}
}