文章目录
- 一、题目
- 二、题解
- 1.基本思路:
- 2.代码:
一、题目
L2-016 愿天下有情人都是失散多年的兄妹
分数 25
全屏浏览
作者 陈越
单位 浙江大学
呵呵。大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人、父母、祖父母、曾祖父母、高祖父母)则不可通婚。本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚?
输入格式:
输入第一行给出一个正整数N(2 ≤ N ≤10 4),随后N行,每行按以下格式给出一个人的信息:
本人ID 性别 父亲ID 母亲ID
其中ID是5位数字,每人不同;性别M代表男性、F代表女性。如果某人的父亲或母亲已经不可考,则相应的ID位置上标记为-1。
接下来给出一个正整数K,随后K行,每行给出一对有情人的ID,其间以空格分隔。
注意:题目保证两个人是同辈,每人只有一个性别,并且血缘关系网中没有乱伦或隔辈成婚的情况。
输出格式:
对每一对有情人,判断他们的关系是否可以通婚:如果两人是同性,输出Never Mind;如果是异性并且关系出了五服,输出Yes;如果异性关系未出五服,输出No。
二、题解
1.基本思路:
- 首先我们可以dfs分别找出两人的五代以内的所有亲戚
- 然后判断两人有没有共同的五代以内的亲戚即可!
- 详解请看代码
2.代码:
#include<bits/stdc++.h>
using namespace std;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define fi first
#define se second
const int N = 1e6+10, INF = 0x3f3f3f3f;
int n,k,flag=0; //flag判断询问中的第一个人还是第二个人
char sex[N]; //记录性别
vector<int> e[N]; //记录关系图
set<int> s1,s2; //保存五代以内的亲戚 void dfs(int u,int dep){if(dep>5) return; //超过五代,过界if(!flag) s1.insert(u); //记录第一个人所有的亲戚 else s2.insert(u); //记录第二个人所有的亲戚
// cout<<u<<' '<<dep<<endl;for(auto j:e[u]){if(j==-1) continue;dfs(j,dep+1);}
}void solve() {cin>>n;for(int i=1;i<=n;i++){int a,b,c;char gender; //性别 cin>>a>>gender>>b>>c;sex[a]=gender;sex[b]='M'; sex[c]='F'; //父母的性别也要记录 e[a].push_back(b);e[a].push_back(c);}cin>>k;while(k--){int a,b; cin>>a>>b;flag=0; s1.clear(); //重置 dfs(a,1); //找a的五代以内的亲戚 flag=1; s2.clear(); //重置 dfs(b,1); //找b的五代以内的亲戚 bool f=false; //开始假设关系超过了五服 for(auto i:s2) if(s1.count(i)) f=true; //没超过五服 if(sex[a]==sex[b]) cout<<"Never Mind"<<endl; //同性 else if(f) cout<<"No"<<endl; //异性,没超过五服 else cout<<"Yes"<<endl; //异性,超过五服 }
}signed main() {
// IOS;int T=1;
// cin>>T;while(T--) {solve();}return 0;
}
/*
*/