|邻接表--关系图dfs|7-12 愿天下有情人都是失散多年的兄妹 (25分)

该博客介绍了如何利用图的邻接链表结构和深度优先搜索算法,解决寻找五代内共同祖先的问题。针对给定的人物关系,通过构建关系图并进行两次DFS遍历,判断情侣之间是否存在近亲关系。示例代码展示了C++实现的详细过程,包括数据结构的选择和搜索策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一题测试数据较长,
实际上题目思路很简单,我们可以将其进行抽象成图的结构,
这样我们就可以用邻接链表来保存祖先的节点即可,最后利用dfs,将A的祖先标记,然后再利用dfs,检查是否已经有标记的,
如果有,那就代表在4代之内通婚,否则没有通婚,
所以dfs结束的条件就是这个搜索深度是否超过4代,
所以dfs搜索的状态就是(x,num);当前正在访问的节点,当前搜索的深度

题解
和L2-030冰岛人类似,但有的点比他容易
实现的话,很容易
数据结构:有父,有母,说明这不是一个普通的树
更像是一种图,肯定还是用存图的方法来存他
然后,利用BFS或者DFS进行搜索

  1. 可以把5代之内的祖先都找到,然后两个循环对比
  2. 利用BFS同时进行查找,在找的过程中进行标记,如果在查找的时候,发现他的一个祖先已经被查过了,这样肯定是有共同祖先
    题目说的是“两个人最近的共同祖先如果在五代以内”
    这一点要比冰岛人简单,冰岛人有可能一方是5代之内,另一方出5代…
    很坑的是,这样正常做下来,就17分
    有可能数据中的父母也被查询到,这个时候判断的是性别
    不能只记录自己的性别

对于查找异性情侣是否存在近亲关系,我的思路很简单,先将其中一个人五代之内与他有亲属关系的人全部做标记,在查找另一个人五代之内的亲属,如果亲属中有人带有标记,说明这对情侣不能结婚,反之可以结婚。
方法:用二维数组或vector容器存关系图,然后对两个人深搜或广搜找出五服里所有亲属。
以第七对情侣为例:
在这里插入图片描述
在上面这两颗关系树中没有出现相同的亲属,所以他们没有近亲关系。输出Yes。

再以不能结婚的最后一组情侣为例:
在这里插入图片描述
在第三层中出现已经标记过的人,说明这两个人是近亲关系,输出No。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

vector<int >parent[100010];
char sex[100010];
int vis[100010];
int flag;

void dfs(int nums,int id){
   //num表示从第几代开始,从0开始(层数)//id为编号
    if(nums>=4){
   
        return;
    }else{
   
        for(int j=0;j<parent[id].size();j++){
   
            if(!vis[parent[id][j]]){
   
                vis[parent[id][j]]=1;//标记出现过的人
                dfs(nums+1,parent[id][j]);
            }else{
   
                flag=1;//
            }
        }
    }
    
}

// void dfs(int index,int num){//num表示从第几代开始,从0开始
//     if(num>=4)return;//超过5代直接退出(从0开始)
//     else{
   
//         for(int j=0;j<parent[index].size();j++){
   
//             if(!vis[parent[index][j]]){//[parent[index][j]编号为index的父母的编号,没被访问过
//                 vis[parent[index][j]]=1;//标记出现的人
//                 dfs(parent[index][j],num+1);
//             }else flag=1;//[parent[index][j]编号为index的父母的编号,被访问过
//         }
//     }
    
    
// }
int main()
{
   
    int n;
    cin>>n;
    for(int i=0;i<n;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值