这一题测试数据较长,
实际上题目思路很简单,我们可以将其进行抽象成图的结构,
这样我们就可以用邻接链表来保存祖先的节点即可,最后利用dfs,将A的祖先标记,然后再利用dfs,检查是否已经有标记的,
如果有,那就代表在4代之内通婚,否则没有通婚,
所以dfs结束的条件就是这个搜索深度是否超过4代,
所以dfs搜索的状态就是(x,num);当前正在访问的节点,当前搜索的深度
题解
和L2-030冰岛人类似,但有的点比他容易
实现的话,很容易
数据结构:有父,有母,说明这不是一个普通的树
更像是一种图,肯定还是用存图的方法来存他
然后,利用BFS或者DFS进行搜索
- 可以把5代之内的祖先都找到,然后两个循环对比
- 利用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;