CCCC团体程序设计天梯赛 L2-016 愿天下有情人都是失散多年的兄妹
记录天梯赛题目合集 跳转查看
题目描述
呵呵。大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人、父母、祖父母、曾祖父母、高祖父母)则不可通婚。本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚?
输入格式:
输入第一行给出一个正整数\(N\)(\(2 \le N \le 10^4\) ),随后\(N\)行,每行按以下格式给出一个人的信息:
本人ID 性别 父亲ID 母亲ID
其中ID是5位数字,每人不同;性别M代表男性、F代表女性。如果某人的父亲或母亲已经不可考,则相应的ID位置上标记为-1。
接下来给出一个正整数\(K\),随后\(K\)行,每行给出一对有情人的ID,其间以空格分隔。
注意:题目保证两个人是同辈,每人只有一个性别,并且血缘关系网中没有乱伦或隔辈成婚的情况。
输出格式:
对每一对有情人,判断他们的关系是否可以通婚:如果两人是同性,输出Never Mind;如果是异性并且关系出了五服,输出Yes;如果异性关系未出五服,输出No。
题目解析
首先根据题目给出的数据建立祖辈图,因为要根据小辈来搜索长辈,建图时将长辈放入小辈的子集中,方便搜索,可以知道会建立一个二叉树。
判断时,不需真的用最近公共祖先算法,可以将每人的五代内长辈标记出来,如果有重复,就没有超过五服,标记使用dfs向下搜索4层即可,最坏情况下也就搜索30个数据(\(K\) 的数据范围不明确,但不太可能超过\(10^6\),不会超时)。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <stack>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const ll inf = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
int n, k;
vector<int> g[N];
char sex[N];
bool st[N];
bool dfs(int u, int stp)
{
	st[u] = 1;
	if (stp > 3) return false;
	
	for (int v : g[u]) {
		if (!st[v]) {
			if (dfs(v, stp + 1)) return true;
		}
		else return true;
	}
	return false;
}
void solve()
{
	cin >> n;
	for (int i = 0; i < n; i ++) {
		int x, fa, ma;
		char c;
		cin >> x >> c >> fa >> ma;
		sex[x] = c;
		if (fa != -1) {
			g[x].push_back(fa);
			sex[fa] = 'M';
		}
		if (ma != -1) {
			g[x].push_back(ma);
			sex[ma] = 'F';
		}
	}
	cin >> k;
	while (k --) {
		int x, y;
		cin >> x >> y;
		if (sex[x] == sex[y]) cout << "Never Mind" << '\n';
		else {
			memset(st, 0, sizeof st);
			dfs(x, 0);
			if (dfs(y, 0)) cout << "No" << '\n';
			else cout << "Yes" << '\n';
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	
	int T = 1;
//	cin >> T;
	while (T --) solve();
	return 0;
}

                
            
        
浙公网安备 33010602011771号