PAT [L2-016] may all lovers in the world be brothers and sisters who have been separated for many years (dfs super detailed explanation)

Posted by rinteractive on Sat, 15 Jan 2022 05:17:13 +0100

Original title

ha-ha. As we all know, intermarriage is not allowed within five clothes, that is, if the nearest common ancestor of two people is within five generations (i.e. myself, parents, grandparents, great grandparents and high grandparents), they cannot intermarry. Please help a couple to judge whether they can get married or not?

Input format:

Enter the first line to give a positive integer N (2 ≤ N ≤ 10 ^ 4), and then N lines. Each line gives a person's information in the following format:

My ID gender father ID mother ID
The ID is 5 digits, which is different for each person; Gender M stands for male and F for female. If a person's father or mother is no longer available, the corresponding ID position is marked with - 1.

Next, a positive integer k is given, followed by K lines. Each line gives a pair of lover ID S separated by spaces.

Note: the title ensures that two people are of the same generation, each has only one gender, and there is no incest or marriage between generations in the blood relationship network.

Output format:

For each pair of lovers, judge whether their relationship can be intermarried: if they are of the same sex, output Never Mind; If it is heterosexual and related to five clothes, output Yes; If the heterosexual relationship does not produce five clothes, output No.

Input example:

24
00001 M 01111 -1
00002 F 02222 03333
00003 M 02222 03333
00004 F 04444 03333
00005 M 04444 05555
00006 F 04444 05555
00007 F 06666 07777
00008 M 06666 07777
00009 M 00001 00002
00010 M 00003 00006
00011 F 00005 00007
00012 F 00008 08888
00013 F 00009 00011
00014 M 00010 09999
00015 M 00010 09999
00016 M 10000 00012
00017 F -1 00012
00018 F 11000 00013
00019 F 11100 00018
00020 F 00015 11110
00021 M 11100 00020
00022 M 00016 -1
00023 M 10012 00017
00024 M 00022 10013
9
00021 00024
00019 00024
00011 00012
00022 00018
00001 00004
00013 00016
00017 00015
00019 00021
00010 00011

Output example:

Never Mind
Yes
Never Mind
No
Yes
No
Yes
No
No

Idea:

This question is difficult. First of all, the meaning of the question should be understandable. The title says that intermarriage is not allowed within five generations. From this point of view, we can define a variable flag to judge: whether the grandparents of the couple have visited repeatedly. If they have visited repeatedly, we can conclude that they are close relatives. Here, we must remember to judge within five generations. If we exceed it, we must exit the cycle.

The rest can be judged by dfs. Here's another point to note: input parents should store their gender, otherwise they can't judge gender later. Moreover, if it is - 1, it does not need to be saved, so there will be an error when saving it to the array (the index of the array cannot be - 1)

At this point, the problem should be very clear. The rest can be understood by looking at the comments of the code. If you don't understand anything, please go to the comment area for communication O(∩ ∩) O~

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
char sex[maxn];	//Record gender
bool vis[maxn];	//Mark whether to access
bool flag;				//Mark close relatives
vector<int>vec[maxn];	//Storage diagram


void dfs(int x, int num)			//Start with the number and generation, and start with 0
{
	if (num >= 4)	return;
	for (int i = 0; i < vec[x].size(); ++i)
	{
		if (!vis[vec[x][i]])
		{
			vis[vec[x][i]] = 1;		//Mark who appears
			dfs(vec[x][i], num + 1);
		}
		else {
			flag = 1;	//They are close relatives
			return;
		}
	}
}
int main()
{
	int n;
	cin >> n;
	char sexx;
	int num, dad, mom;
	while (n--)
	{
		scanf("%d %c %d %d", &num, &sexx, &dad, &mom);
		//cin >> num >> sexx >> dad >> mom;
		sex[num] = sexx;
		if (dad != -1)
		{
			vec[num].push_back(dad);
			sex[dad] = 'M';
		}
		if (mom != -1)
		{
			vec[num].push_back(mom);
			sex[mom] = 'F';
		}
	}
	cin >> n;
	int person1, person2;
	while (n--)
	{
		scanf("%d %d", &person1, &person2);
		if (sex[person1] == sex[person2])
			cout << "Never Mind" << endl;
		else
		{
			fill(vis, vis + maxn, 0);
			flag = 0;
			vis[person1] = vis[person2] = 1;
			dfs(person1, 0);
			dfs(person2, 0);
			if (flag)
				cout << "No" << endl;
			else
				cout << "Yes" << endl;
		}
	}

	return 0;
}

Topics: Algorithm data structure dfs