L2-016 愿天下有情人都是失散多年的兄妹 (变态题)

本题传送门
难爆了。

解题思路

这题可能唯一能蹦出来的思路就是用结构体存信息😭

这道题要看二人最后是否能成眷属 , 有以下条件:

1. 性别不同(-_-||)

2. 二人的最近的共同祖先如果在五代以内就不能通婚(可能是没有共同祖先,也有可能是祖先在五代之外)

对于要检测的二人,我们可以对其中一个进行祖宗遍历,把家庭里所有的人标记一下,然后再遍历另一个人,如果在遍历的过程中发现有个人已经被标记过了
(这样的事情,千万不要啊o(╥﹏╥)o)就失败了,collsion = true;当然,如果遍历的层数超过了5,就直接结束了

  • 上面遍历的过程是不一样的,要么我们写两个函数,要么可以在一个函数里用两个mode,一个专门标记,另一个专门检测。

好像很简单?对的,对的,对的?不对,不对,不对。

ac✅️代码

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

struct Node{
	int f = -1,m = -1;
	char sex;
}p[100001];

bool vis[100005];
bool collision = false;

void dfs(int u,int depth,int mode)
{
     //由于父代或母代可能已经不可考,所以还要判断一下u
	if(depth > 5 || u == -1) return ;
	
	if(mode == 1)
	{
		vis[u] = true;
	}
	else
	{
		if(vis[u])
		{
			collision = true;
			return ;
		}
	}
	//遍历父亲那一代
	dfs(p[u].f , depth + 1 , mode);
    //剪枝
	if(collision) return ;
    //遍历母亲那一代
	dfs(p[u].m, depth+1,mode);
	
}

int main()
{
	int n;cin>>n;
	for(int i = 0 ; i < n ; i++)
	{
		int id,f,m;
		char s;
		cin>>id>>s>>f>>m;
		p[id].sex = s;
		p[id].f = f;
		p[id].m = m;
		if(f != -1) p[f].sex = 'M';
		if(m != -1) p[m].sex = 'F';
	}
	
	int k;
	cin>>k;
	while(k--)
	{
		int a,b;
		cin>>a>>b;
		if(p[a].sex == p[b].sex) cout<<"Never Mind\n";
		else 
		{
			memset(vis,false,sizeof vis);
			collision = false;
			dfs(a,1,1);
			dfs(b,1,2);
			if(collision) cout<<"No\n";
			else cout<<"Yes\n";
		}
		
	}
	return 0;

}
posted @ 2026-03-15 15:44  shuiwangrenjia  阅读(1)  评论(0)    收藏  举报