7-14 小字辈 (25 分)-1下标坑死我了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

本文通过DFS和BFS两种方法,详细解析了如何在庞大家族家谱中找到最小辈分成员的问题,分享了从错误中学习,避免非法下标访问的宝贵经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。
输入格式:
输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。
输出格式:
首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。
输入样例:
9
2 6 5 5 -1 5 6 4 7
输出样例:
4
1 9

写这道题的时候真是一波三折,一看题,这不是个dfs水题吗=w=,想着直接dfs搞定了,三下五除二写了个结构存数据,两个元素一个存爹,一个容器存儿子,然后输入数据的时候先进入对应i的下标存父亲,然后进入父亲的下标存儿子。。
本来是这样一个很简单的题,然后里面有一个老祖宗的父亲用-1表示,如果输入-1就进入-1下标保存儿子。但是进入-1的话会出错,结果就这一点没发现,耽误了好久(读取-1下标IDE竟然没报错我的天哪,要不然那还有这么多事)。我就换了好多种做法,一开始dfs递归搜索,结果pta
在这里插入图片描述
(这个破问题花了我50分钟写了三种方法,结果就少了一个continue)
然后我就蒙了,以为是递归爆栈了。就换成无限循环找-1父亲然后存层数,结果还是所有测试点运行出错,当时以为是超时出错(明明显示运行时错误啊),我就又换成BFS层序遍历存层数。然后还是运行出错,当时我就急了。感觉不对劲,是不是前面错了,然后调试IDE也没报错,给的输入样例也对。就从头一行一行的看啊,肉体调试大法。一看到这个下标会等于-1…再一看访问了…emmmmm,心情复杂,把前面的三种做法全都加了个continue,再一看三个方法ac两个,循环超时,最后我就来写这篇博了。。
得出来的结论就是。。。写代码的时候一定要小心,对于这种访问的下标一定要检查再检查有没有非法的数据,如果有没注意到的下标然后IDE还不提示,可能会走很多弯路QAQ
把ac的两种方法贴出来吧
DFS递归:

#include<iostream>
#include<vector>
using namespace std;
struct TNode
{
	int father;
	vector<int>child;
}List[100000];
int maxb = 1;
void dfs(vector<int>&l, int b, int s)
{
	if (!(List[s].child.size()))
		return;
	for (int i = 0; i < List[s].child.size(); i++)
	{
		l[List[s].child[i]] = b;
		if (b > maxb)
			maxb = b;
		dfs(l, b + 1, List[s].child[i]);
	}
	return;
}
int main()
{
	int n;
	cin >> n;
	int root;
	vector<int>level(n + 1);
	for (int i = 1; i <= n; i++)
	{
		cin >> List[i].father;
		if (List[i].father == -1)//万恶之源!!!!!!!!!
		{
			root = i;
			continue;
		}
		List[List[i].father].child.push_back(i);
	}
	level[root] = 1;
	dfs(level, 2, root);
	int flag = 1;
	cout << maxb << endl;
	for (int i = 1; i <= n; i++)
	{
		if (level[i] == maxb)
		{
			if (flag)
			{
				cout << i;
				flag = 0;
			}
			else
				cout << " " << i;
		}
	}
	return 0;
}

竟然没超时/爆栈?
没有超时

BFS层序遍历:

#include<iostream>
#include<vector>
#include<deque>
using namespace std;
struct TNode
{
	int father;
	vector<int>child;
}List[100000];
int maxb = 1;
void cxbl(vector<int>&l, int s)
{
	deque<int>dl;
	dl.push_back(s);
	while (dl.size())
	{
		int a = dl.front();
		dl.pop_front();
		for (int i = 0; i < List[a].child.size(); i++)
		{
			l[List[a].child[i]] = l[a] + 1;
			if (l[a] + 1 > maxb)
				maxb = l[a] + 1;
			dl.push_back(List[a].child[i]);
		}
	}
	return;
}
int main()
{
	int n;
	cin >> n;
	int root;
	vector<int>level(n + 1);
	for (int i = 1; i <= n; i++)
	{
		cin >> List[i].father;
		if (List[i].father == -1)//万恶之源!!!!!!!!!
		{
			root = i;
			continue;
		}
		List[List[i].father].child.push_back(i);
	}
	level[root] = 1;
	cxbl(level, root);
	int flag = 1;
	cout << maxb << endl;
	for (int i = 1; i <= n; i++)
	{
		if (level[i] == maxb)
		{
			if (flag)
			{
				cout << i;
				flag = 0;
			}
			else
				cout << " " << i;
		}
	}
	return 0;
}

BFS这个方法应该是比较科学的
BFS

IDE为什么不报错!!!!啊啊啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值