7-1 愿天下有情人都是失散多年的兄妹 --DFS

本文介绍了一种算法,用于判断两个人的关系是否超出五服,以此来决定他们是否可以合法结婚。通过构建血缘关系图并使用深度优先搜索(DFS),算法能够确定两个人的最近共同祖先是否在五代以内。

7-1 愿天下有情人都是失散多年的兄妹 (25分)

呵呵。大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人、父母、祖父母、曾祖父母、高祖父母)则不可通婚。本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚?

输入格式:

输入第一行给出一个正整数N(2 ≤ N ≤10^4​​ ),随后N行,每行按以下格式给出一个人的信息:
本人ID 性别 父亲ID 母亲ID

其中ID是5位数字,每人不同;性别M代表男性、F代表女性。如果某人的父亲或母亲已经不可考,则相应的ID位置上标记为-1。

接下来给出一个正整数K,随后K行,每行给出一对有情人的ID,其间以空格分隔。

注意:题目保证两个人是同辈,每人只有一个性别,并且血缘关系网中没有乱伦或隔辈成婚的情况。

输出格式:

对每一对有情人,判断他们的关系是否可以通婚:如果两人是同性,输出Never Mind;如果是异性并且关系出了五服,输出Yes;如果异性关系未出五服,输出No

输入样例

24
00001 M 01111 -1
00002 F 02222 03333
00003 M 02222 03333
00004 F 04444 03333
00005 M 04444 05555
00006 F 04444 05555
00007 F 06666 07777
00008 M 06666 07777
00009 M 00001 00002
00010 M 00003 00006
00011 F 00005 00007
00012 F 00008 08888
00013 F 00009 00011
00014 M 00010 09999
00015 M 00010 09999
00016 M 10000 00012
00017 F -1 00012
00018 F 11000 00013
00019 F 11100 00018
00020 F 00015 11110
00021 M 11100 00020
00022 M 00016 -1
00023 M 10012 00017
00024 M 00022 10013
9
00021 00024
00019 00024
00011 00012
00022 00018
00001 00004
00013 00016
00017 00015
00019 00021
00010 00011

输出样例

Never Mind
Yes
Never Mind
No
Yes
No
Yes
No
No

DFS就和树的先序遍历,好理解是好理解,就是代码不太会用,也不太会用到题目中,不熟练,DFS的代码板块理解可以参考这篇文章:DFS(深度优先搜索算法)

#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
const int maxn = 100002;
bool v[maxn];   //判断是否访问
typedef struct peo
{
	int id;
	bool sex;
}peo;
vector<int> G[maxn];
peo man[maxn];
bool flag;
void dfs(int x,int y)
{
	if (!y||flag)
		return;
	v[x] = 1;
	for (int k = 0; k < G[x].size(); k++)
	{
		int u = G[x][k];
		if (u == -1)
			continue;
		if (v[u])   //如果五服以内出现了共同祖先
		{
			flag = true;
			return;
		}	
		dfs(u, y - 1);
		//用y--原地爆炸,懂得都懂,就是我不懂,C语言白学
	}
}
int main()
{
	int n,m,fa,ma,a;
	char sexu;
	int id1, id2;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> a >> sexu >> fa >> ma;
		man[a].id = a;
		man[a].sex = (sexu == 'M');
		man[fa].id = fa;
		man[fa].sex = 1;
		man[ma].id = ma;
		man[ma].sex = 0;
		G[a].push_back(fa);
		G[a].push_back(ma);
	}
	cin >> m;
	for (int i = 0; i < m; i++)
	{
		memset(v, 0, sizeof(v));
		cin >> id1 >> id2;
		if (man[id1].sex == man[id2].sex)
			cout << "Never Mind" << endl;
		else
		{
			flag = false;
			dfs(id1, 5);
			dfs(id2, 5);
			if (flag == true)
				cout << "No" << endl;
			else
				cout << "Yes" << endl;
		}
	}
	return 0;
}
这个有趣的说法似乎是在引用网络流行语,但它并不是一个直接的编程题目。然而,如果你想要了解如何用C语言实现深度优先搜索(DFS),这是一个经典的图遍历算法,可以模拟查找两个节点之间的径。以下是使用DFS的一个简单示例,假设我们有一个无向图,用邻接表表示: ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int value; struct Node* next; } Node; void DFS(Node** graph, int start, int goal) { Node* current = *graph[start]; while (current != NULL) { if (current->value == goal) { printf("找到了! %d -> %d\n", start, goal); return; } // 递归遍历当前节点的所有邻居 DFS(graph, current->value, goal); current = current->next; } printf("未找到径从 %d 到 %d\n", start, goal); } // 添加边到邻接表 void addEdge(Node** graph, int src, int dst) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->value = dst; newNode->next = graph[src]; graph[src] = newNode; } int main() { int n; // 图的节点数 printf("请输入节点数:"); scanf("%d", &n); Node** graph = (Node**)malloc(n * sizeof(Node*)); for (int i = 0; i < n; ++i) { graph[i] = NULL; } // 根据输入添加边 for (int i = 0; i < n - 1; ++i) { int u, v; printf("请输入边 (%d, %d): ", i + 1, i + 2); scanf("%d %d", &u, &v); addEdge(&graph[u - 1], v - 1, i + 1); // 减一操作将用户输入转换为数组索引 } int start, end; printf("请输入开始节点和目标节点:"); scanf("%d %d", &start, &end); DFS(graph, start - 1, end - 1); // 再次减一处理用户输入 return 0; } ``` 这个程序首先创建一个邻接表来存储图,然后根据用户的输入添加边,并执行深度优先搜索来查找指定起点和终点之间的径。请注意,这里的"失散多年兄妹"是一个比喻,实际上这里我们在找径。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值