很有意思的一道题目,因为是两个人是同辈的,所以我们只需要向上找五代以内的直系亲戚即可。对于u,v这两个人的判断,先找出u的所有亲戚,放到一个set里面,再找v的亲戚用set判断就行了。
不过这里要注意下面的询问里面不仅仅是N以内的人,还有可以能是列表中出现的所有人,所以对于每个点的父,母也要建立节点存储。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 100010;
typedef pair<int,int> P;
struct Node{//存储每个人的信息
int father;
int monther;
char sex;
Node();
Node(int _f,int _m,char _s);
};
Node myself[MAX];
bool used[MAX];
int N;
vector<int> all;
void BFS(int B){
memset(used,false,sizeof(used));
queue<P> que;
que.push(P(B,1));
//找出这个人向上五代的直系亲戚
used[B] = true;
while(!que.empty()){
P v = que.front();que.pop();
all.push_back(v.first);
int F = myself[v.first].father;
int M = myself[v.first].monther;
// cout << "F = " << F << " M = " << M << endl;
int step = v.second + 1;
if(step > 5) continue;
if(F != -1 && !used[F]){
used[F] = true;
que.push(P(F,step));
}
if(M != -1 && !used[M]){
used[M] = true;
que.push(P(M,step));
}
}
}
int solve(int u,int v){
if(myself[u].sex == myself[v].sex)
return -1;
all.clear();//注意清空
BFS(u);
set<int> st;
for(vector<int>::iterator it = all.begin();it != all.end();++it){
st.insert(*it);
// cout << *it << endl;
}
all.clear();
BFS(v);
for(vector<int>::iterator it = all.begin();it != all.end();++it){
if(st.count(*it))
return 0;
}
return 1;
}
int main(void){
cin >> N;
int ID,FID,MID;
char sex;
for(int i=1;i<=N;++i){
cin >> ID >> sex >> FID >> MID;
myself[ID].father = FID;
myself[ID].monther = MID;
myself[ID].sex = sex;
if(FID != -1)
myself[FID].sex = 'M';//父母也要建立节点
if(MID != -1)
myself[MID].sex = 'F';
}
int K,u,v;
vector<int> res;
cin >> K;
for(int i=1;i<=K;++i){
cin >> u >> v;
res.push_back(solve(u,v));
}
for(vector<int>::iterator it = res.begin();it != res.end();++it){
if(*it == 1) cout << "Yes" << endl;
else if(*it == 0) cout << "No" << endl;
else cout << "Never Mind" << endl;
}
return 0;
}
Node::Node(){
father = monther = -1;
sex = 'M';
}
Node::Node(int _f,int _m,char _s){
father = _f;
monther = _m;
sex = _s;
}