-
-
关于思路:
- 题目概述:呵呵。大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人、父母、祖父母、曾祖父母、高祖父母)则不可通婚。本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚?
输入第一行给出一个正整数N(2 ≤ N ≤10000),随后N行,每行按以下格式给出一个人的信息
本人ID 性别 父亲ID 母亲ID
其中ID是5位数字,每人不同;性别M代表男性、F代表女性。如果某人的父亲或母亲已经不可考,则相应的ID位置上标记为-1。
- 首先了解题意:
从题目给出的各种亲戚关系中判断测试样例是否可以结婚(即为是否在五服内)
- 思路: 由题目输入构建关系网(使用数组实现),对于每个询问,首先初始化关系网数组内的亲戚标记(或许可以叫做染色?),再使用递归的方式,对每个询问中的主角进行问候(祖宗),如果未标记,则标记,如果已经标记,则说明询问中的两个主角的亲戚关系网有重叠的部分,则询问的回答为否(关系在五服内不能成婚)。
问题1.构建关系网(数组实现):首先声明一个二维数组a[maxn]5,对于每个数组元素x,都有a[x][0]为性别,a[x][1]a[x][2]a[x][4]分别为父母id与“染色体”。
问题2.使用递归的方法进行染色体标记:递归功能主要在于1.对给定目标的染色体进行染色,若该染色体已被染色,说明五服内有重叠,此时则返回一个否定值2.若染色成功,则对该一元素数组下的父母id进行深入染色
-
代码:
AC代码
#include<stdio.h>
int a[111111][5];
void colorclear()
{
for (int i=0;i<=111100;i++)
{
a[i][4]=-1;
}
}
void clear()
{
for (int i=0;i<=111100;i++)
{
a[i][4]=-1;
a[i][0]=-1;
a[i][1]=-1;
a[i][2]=-1;
}
}
int flag=0;
int search(int q,int s)
{
if (s==5)
{return 0;}
if (a[q][4]!=1)
{
a[q][4]=1;
}
else
{
flag=1;
return ;
}
for (int i=1;i<=2;i++)
{
if (a[q][i]!=-1)
{
search(a[q][i],s+1);
}
}
}
int main()
{
int n,q,qq,qqq;
char c;
scanf("%d",&n);
getchar();
clear();
for (int i=1;i<=n;i++)
{
scanf("%d %c %d %d",&q,&c,&qq,&qqq);
getchar();
if (c=='F')
{a[q][0]=0;}
else
{a[q][0]=1;}
a[q][1]=qq;
a[q][2]=qqq;
if (qq!=-1)
{a[qq][0]=1;}
if (qqq!=-1)
{a[qqq][0]=0;}
}
/*for (int i=1;i<=n;i++)
{
printf("%d %d %d\n",i,a[i][1],a[i][2]);
}*/
scanf("%d",&n);
int x,b;
for (int i=1;i<=n;i++)
{
colorclear();
flag=0;
scanf("%d %d",&x,&b);
search(x,0);
search(b,0);
if (a[x][0]==a[b][0])
{
printf("Never Mind\n");
}
else if (flag==1)
{
printf("No\n");
}
else
{
printf("Yes\n");
}
}
}