1.题目
法一:DFS+并查集
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node
{
int father; // 父亲
int mather; // 母亲
char sex; // 性别
}a[N];
int n, k;
int i, j; // 遍历
int id, father, mather; // 孩子,父,母
char sex; // 性别
int x, y; // 需要判断的两个人
int pre[N]; // 并查集数组
int find(int x)
{
if(x != pre[x]) pre[x] = find(pre[x]);
return pre[x];
}
void Union(int a, int b)
{
if (b == -1)
return;
pre[find(b)] = find(a);
}
bool dfs(int x, int y, int age)
{
if ( x == -1 || y == -1)
return true;
if (age > 5)
return true;
if (x == y)
return false;
else
return dfs(a[x].father, a[y].father, age + 1) && dfs(a[x].father, a[y].mather, age + 1) && dfs(a[x].mather, a[y].father, age + 1) && dfs(a[x].mather, a[y].mather, age + 1);
}
int main()
{
for (int i = 0; i < N; i++)
{
pre[i] = i;
a[i].father = -1;
a[i].mather = -1;
}
cin >> n;
while (n -- )
{
scanf("%d %c %d %d", &id, &sex, &father, &mather);
a[id].father = father;
a[id].sex = sex;
a[id].mather = mather;
// 将孩子与父母联系起来
Union(id, father);
Union(id, mather);
// 父母的性别
if (father != -1)
a[father].sex = 'M';
if (mather != -1)
a[mather].sex = 'F';
}
cin >> k;
while(k--)
{
scanf("%d %d", &x, &y);
// 先判断性别
if (a[x].sex == a[y].sex)
puts("Never Mind");
else
{
if (find(x) != find(y))
puts("Yes");
else if (dfs(x, y, 1))
puts("Yes");
else
puts("No");
}
}
return 0;
}
法二:DFS+标记
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int Inf=1e5+5;
vector<int> vec[Inf];//存关系图
bool vis[Inf];//标记五服以内的亲属
char sex[Inf];//记录性别
bool flag;//标记情侣是否为近亲
void Dfs(int x,int num)//num表示第几代,从0开始
{
if(num > 4)//超过五代直接退出
return;
for(int i=0;i<vec[x].size();i++)
{
if(!vis[vec[x][i]])
{
vis[vec[x][i]]=1;//标记出现的人
Dfs(vec[x][i],num+1);
}
else
flag=1;//五服之内出现一样的人
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
int t,fa,ma;
char ch;
scanf("%d ",&t);
sex[t]=getchar();
scanf(" %d %d",&fa,&ma);
if(fa!=-1) //-1不用保存,避免数据处理不当导致数组越界
{
vec[t].push_back(fa);//保存双亲
sex[fa]='M';//记录父亲性别
}
if(ma!=-1)
{
vec[t].push_back(ma);
sex[ma]='F';
}
}
cin>>T;
while(T--)
{
int x,y;
scanf("%d %d",&x,&y);
if(sex[x]==sex[y])//同性
cout<<"Never Mind"<<endl;
else
{
memset(vis,0,sizeof(vis));
vis[x]=1;
vis[y]=1;
flag=0;
Dfs(x,0);
Dfs(y,0);
if(flag)//被标记过说明这两人为近亲
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
}
return 0;
}