天梯赛L2-026 小字辈 (25 分)
题目详情:
输入样例:
9
2 6 5 5 -1 5 6 4 7
输出样例:
4
1 9
思路:
这个题目当时写了一种递归的方法,但是递归的不好,测试数据太大了,导致有几个测试点一直超时,后面从网上看了看大佬的方法,就知道如何修改自己的递归了。
先附上修改后的代码:
详细代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 5;
int pre[maxn];//存前驱节点
int n, level[maxn];//存辈分,全局变量默认为0
int dfs(int u)
{
if(level[u] == 0)//如果一个人的辈分已经知道了,就不用在遍历它了
{
if(pre[u] == -1)//辈分最大的为1
{
level[u] = 1;
}
else
{
level[u] = dfs(pre[u]) + 1;//递归:找父结点的辈分
}
}
return level[u];
}
int main( )
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>pre[i];
}
int max = 0;//当pta每次提交的分数不一样时,非常有可能是定义的变量没有赋值的原因!!!
int temp;
for(int i=1; i<=n; i++)
{
temp = dfs(i);
if(temp > max)//找到最小辈分
max = temp;
}
cout<<max<<endl;
int count = 0;
for(int i=1; i<=n; i++)
{
if(level[i] == max)
{
if(count == 1)
cout<<" ";
cout<<i;
count = 1;
}
}
cout<<endl;
知识总结:
再附上超时的代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 5;
int pre[maxn];
int n, level[maxn] ;
void dfs(int u)
{
for(int i=1; i<=n; i++)
{
if(pre[i] == u)
{
level[i] = level[pre[i]] + 1;
dfs(i);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d", &pre[i]);
for(int i=1; i<=n; i++)
{
if(pre[i] == -1)
{
dfs(i);
}
}
int max = level[0];
for(int i=1; i<=n; i++)
{
if(max <= level[i])
max = level[i];
}
printf("%d\n",max+1);
int count=0;
for(int i=1; i<=n; i++)
{
if(level[i] == max)
{
if(count == 1)
printf(" ");
count = 1;
printf("%d",i);
}
}
}