PTA—L2-016 愿天下有情人都是失散多年的兄妹
思路
- 结构体中存爹娘的编号,还有本人的性别…
- 然后搜索5代以内(dfs或者bfs都行),有两种方法看是否通婚
- 1.两个人一起找,如果找到同一节点(祖先),返回false。如果一直找一直找,都没找到共同的,则返回true,当找所有的节点(从源节点出发所有的五代以内的节点都不相交)都是true时,最终返回的是true,那么可以通婚
- 2.先一个人找5代以内的,然后将搜索到的存在一个数组里,再找另一个人五代以内的,如果出现这个book数组当前节点为1(假设访问过赋值为1,没访问为0),则让flag为1,表示不能通婚
- 这里要注意的坑点就是,当你输入当前节点的性别时,要考虑将父母的性别也输入(由于有三个测试点都是测试父母的,输入时并没有定义…)
AC代码
小菜鸟花了一晚上…
#include <iostream>
#include <vector>
using namespace std;
struct person
{
int fa;
int ma;
char gen; //性别
//int age; //表示这个人的代数没用
person()
{
fa = -1;
ma = -1;
// age = 1;
}
};
int book[100000]; //并查集,查询是否是统一祖先
int Find(int x)
{
if(x == book[x])
return x;
return book[x] = Find(book[x]);
}
void merge(int x,int y)
{
if(y == -1)
return ;
x = Find(x);
y = Find(y);
if(x != y) //y是老大 即父母为大
book[x] = y;
return ;
}
void ini()
{
int i=0;
for(i=0;i<100000;i++)
book[i] = i;
}
person a[100000];
//第一种同时找
bool dfs(int x,int y,int age) //true->可以 false->不可
{
if(!(x != -1 && y != -1))
return true;
if(age > 5)
return true;
if(x == y) //这两人祖
{
if(age > 5)
return true;
return false;
}
else
return dfs(a[x].fa,a[y].fa,age+1)&&dfs(a[x].fa,a[y].ma,age+1)&&dfs(a[x].ma,a[y].fa,age+1)&&dfs(a[x].ma,a[y].ma,age+1);
}
//第二种一个一个找
int flag;
void dfs(int cur,int age,int *bk)
{
if(age >= 5)
return ;
if(a[cur].fa != -1)
{
if(bk[a[cur].fa] == 0)
bk[a[cur].fa] = 1,dfs(a[cur].fa,age+1,bk);
else
flag = 1; //表示不可通婚
}
if(a[cur].ma != -1)
{
if(bk[a[cur].ma] == 0)
bk[a[cur].ma] = 1,dfs(a[cur].ma,age+1,bk);
else
flag = 1; //表示不可通婚
}
}
int main()
{
ini();
int n,i,j;
scanf("%d",&n);
for(i=0;i<n;i++)
{
int id,fid,mid;
char sex;
scanf("%d %c %d %d",&id,&sex,&fid,&mid);
a[id].fa = fid;
a[id].gen = sex;
a[id].ma = mid;
//a[id].age += a[fid].age; //等全部输入完成后再进行
merge(id,fid);
merge(id,mid);
//下面两个非常关键...
if(fid != -1)
a[fid].gen = 'M';
if(mid != -1)
a[mid].gen = 'F';
}
int k;
scanf("%d",&k);
for(i=0;i<k;i++)
{
int x,y;
scanf("%d %d",&x,&y);
int xx = Find(x);
int yy = Find(y);
if(a[x].gen == a[y].gen) //相同性别
printf("Never Mind\n");
else
{
if(xx != yy) //不同祖先
printf("Yes\n");
//方法一
else if(dfs(x,y,1)) //相同祖先
printf("Yes\n");
else
printf("No\n");
//方法二
/*
else
{
int bk[100000] = {0};
flag = 0;
bk[x] = 1;
bk[y] = 1;
dfs(x,1,bk);
dfs(y,1,bk);
if(flag)
printf("No\n");
else
printf("Yes\n");
}
*/
}
}
return 0;
}