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;
}