L2-016 愿天下有情人都是失散多年的兄妹(暴力深搜)
输入样例:
24
00001 M 01111 -1
00002 F 02222 03333
00003 M 02222 03333
00004 F 04444 03333
00005 M 04444 05555
00006 F 04444 05555
00007 F 06666 07777
00008 M 06666 07777
00009 M 00001 00002
00010 M 00003 00006
00011 F 00005 00007
00012 F 00008 08888
00013 F 00009 00011
00014 M 00010 09999
00015 M 00010 09999
00016 M 10000 00012
00017 F -1 00012
00018 F 11000 00013
00019 F 11100 00018
00020 F 00015 11110
00021 M 11100 00020
00022 M 00016 -1
00023 M 10012 00017
00024 M 00022 10013
9
00021 00024
00019 00024
00011 00012
00022 00018
00001 00004
00013 00016
00017 00015
00019 00021
00010 00011
输出样例:
Never Mind
Yes
Never Mind
No
Yes
No
Yes
No
No
查询是否五代以内,本来还打算用LCA做(虽然我很生算是不会…)但这不是树。因为可以一个人可与多个人同时拥有孩子 反正就这些啦(我没有描述对,自己轻轻想想就好了)
五代啊,这是多么小的数字啊,直接暴力深搜就OK,先把a的五代祖先标记,看b的五代祖先是否与之重合。
#include<cstdio>
#include<cstring>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=100000+5;
int fa[N],ma[N],sex[N],vis[N];(每个人的id也比较小,用数组)
void dfs1(int x,int k)
{
if(k==6||x==-1)
return;
vis[x]=1;
dfs1(fa[x],k+1);
dfs1(ma[x],k+1);
}
int dfs2(int x,int k)//这个根本不用一个flag,起不到提前返回的作用,本身已经很提前返回了
{
if(k==6||x==-1)
return 1;
if(vis[x])
return 0;
if(!dfs2(fa[x],k+1))
return 0;
return dfs2(ma[x],k+1);
}
int main()
{
m(sex,-1),m(fa,-1),m(ma,-1);
int m;scanf("%d",&m);
while(m--)
{
int id;char s[2];
scanf("%d%s",&id,s);
sex[id]=(s[0]=='M')?1:0;
scanf("%d%d",&fa[id],&ma[id]);
sex[fa[id]]=1,sex[ma[id]]=0;//千万不要忘记了呀啊啊啊
}
int q;scanf("%d",&q);
while(q--)
{
int a,b;scanf("%d%d",&a,&b);
if(sex[a]==sex[b])
puts("Never Mind");
else
{
m(vis,0);
dfs1(a,1);
puts(dfs2(b,1)?"Yes":"No");
}
}
}