pta l2-16(愿天下有情人都是失散多年的兄妹)

题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805061769609216

题意:两个异性的人五服之内不得通婚,给出n个人的信息,包括id、性别、父母id(父母不可考的为-1),给出k组询问,若两个人同性,输出"Never Mind“,异性可通婚输出Yes,异性不可通婚输出No。

思路:看完题就感觉是个并查集的题,然后一直在往并查集这个方向想,可是怎么也想不到怎么处理五代之内的祖先的问题,无奈去查了下,看到别人的思路是dfs,醍醐灌顶,对啊,数据这么小,直接搜索两个人的五代之内的祖先有没有交集不就行了,唉,还是做的题目太少了,容易局限于一个角度。

  好了,回归题目,这个题目有个很坑的地方,输入的询问可能会问到没有出现的id,这种情况就不会有近亲的可能,但不知道其性别,所以其性别可M可F。因为id为5位,我们1e5+5大小的结构体数组就可存所有人的信息了,结构体中包含性别,父母id,因为上面提到其性别可能出现3种情况,因此用0表示可M可F,用1表示M,用2表示F;父母id初始化为-1,输入个人信息的时候要注意要同时初始化其父母的性别,父为M,母为F。回答询问时若出现未出现的人直接输出”Yes“,若两人性别相同输出”Never Mind“(^_^),最后一种为异性情况,用dfs1搜索t1五代以内的祖先,保存在set中,用dfs2搜索t2五代以内的祖先,若有交集令flag=1,否则flag=0,然后输出相应的信息即可。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 struct node{
 5     int sex,fa,ma;
 6 }a[100005];
 7 
 8 int n,k,t1,t2,t3,flag;
 9 char c;
10 set<int> s;
11 
12 void dfs1(int p,int num){
13     if(num>=5) return;
14     int ff=a[p].fa,mm=a[p].ma;
15     if(ff>=0){
16         s.insert(ff);
17         dfs1(ff,num+1);
18     }
19     if(mm>=0){
20         s.insert(mm);
21         dfs1(mm,num+1);
22     }
23 }
24 
25 void dfs2(int p,int num){
26     if(num>=5) return;
27     int ff=a[p].fa,mm=a[p].ma;
28     if(s.count(ff)||s.count(mm)){
29         flag=1;
30         return;
31     }
32     if(ff>=0){
33         dfs2(ff,num+1);
34         if(flag) return;
35     }
36     if(mm>=0){
37         dfs2(mm,num+1);
38         if(flag) return;
39     }
40 }
41 
42 int main(){
43     scanf("%d",&n);
44     for(int i=0;i<100000;++i)
45         a[i].fa=a[i].ma=-1;
46     while(n--){
47         scanf("%d %c%d%d",&t1,&c,&t2,&t3);
48         a[t1].sex=(c=='M')?1:2;
49         a[t1].fa=t2,a[t1].ma=t3;
50         a[t2].sex=1;
51         a[t3].sex=2;
52     }
53     scanf("%d",&k);
54     while(k--){
55         scanf("%d%d",&t1,&t2);
56         if(!a[t1].sex||!a[t2].sex)
57             printf("Yes\n");
58         if(a[t1].sex==a[t2].sex)
59             printf("Never Mind\n");
60         else{
61             flag=0;
62             s.clear();
63             dfs1(t1,1);
64             dfs2(t2,1);
65             if(flag)
66                 printf("No\n");
67             else
68                 printf("Yes\n");
69         }
70     }
71     return 0;
72 }

 

转载于:https://www.cnblogs.com/FrankChen831X/p/10548507.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值