PTA-L2-016 愿天下有情人都是失散多年的兄妹 (25分)

PTA-L2-016 愿天下有情人都是失散多年的兄妹 (25分)

传送门

这道题就是一个dfs

我们标记从子女开始的五代以内的人,用dfs全部都标记为1.然后在dfs中判断是否有已经标记过的人,如果有,那么说明五代以内有共同的祖先。就可以判断输出了。
这里注意两点:
1.我们标记性别的时候不能简单的0,1标记,因为有些是要你自己判断性别的,题目中不会给,如果因为预处理不当很容易直接把不知道性别的人直接默认为0,实际上赋予了其性别,所以我们可以标记为‘M’ / ‘F’,然后在给出父母ID的时候,也需要把性别标记进去。
注意需要特判为-1,因为数组存储,很容易越界,所以-1不处理。
2.五代以内,在dfs中,判断的条件是>=4就返回,因为每次进入dfs之前,我们已经把当前处理的这一代给标记过了。所以我们当前dfs处理的是下一代,所以到4就得返回。(因为从0开始。)所以4代表着第五代,在num = 4时,我们处理的是第六代的情况。第六代不需要处理,所以直接返回了。

代码部分:

#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e5 + 10;
const int M = 55;
const int INF = 1e6 + 10;
typedef long long ll;

int vis[N];
int n;
char s[N];
vector<int> v[N];
int flag;

void dfs(int x, int num)
{
    
    
	if (flag)
	{
    
    
		return ;
	}
	if (num >= 4)
	{
    
    
		return ;
	}
	for (int i = 0; i < v[x].size(); i++)
	{
    
    
		if (!vis[v[x][i]])
		{
    
    
			vis[v[x][i]] = 1;
			dfs(v[x][i], num + 1);
		}
		else
		{
    
    
			flag = 1;
		}
	}
}

int main()
{
    
    
	cin >> n;
	while (n--)
	{
    
    
		int t, fa, ma;
		char sex;
		scanf ("%d %c %d %d", &t, &sex, &fa, &ma);
		s[t] = sex;
		if (fa != -1)
		{
    
    
			v[t].push_back(fa);
			s[fa] = 'M';
		} 
		if (ma != -1)
		{
    
    
			v[t].push_back(ma);
			s[ma] = 'F';
		}
	}
	int k;
	cin >> k;
	while (k--)
	{
    
    
		mst(vis, 0);
		flag = 0;
		int x, y;
		scanf ("%d%d", &x, &y);
		if (s[x] == s[y])
		{
    
    
			cout << "Never Mind\n";
			continue;
		}
		vis[x] = 1;
		vis[y] = 1;
		dfs(x, 0);
		dfs(y, 0);
		if (flag)
		{
    
    
			cout << "No\n";
		}
		else
		{
    
    
			cout << "Yes\n";
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_44624316/article/details/110221729
今日推荐