题14.&2022寒假天梯赛训练&天梯赛训练-小字辈 (25 分)
一、题目
二、题解
本题的关键在于如何找到最小辈,我们可想着将输入的parent与下标作为两个邻接的顶点存入图中,且为parent->i有向边,这样我们只要从祖先顶点开始bfs一层一层遍历图,到最后一层即为最小辈顶点,然后排序输出即可。而bfs确定每个顶点所在层数我们可以用level[i]表示,它的值等于它上一层节点的层数+1。
#include <bits/stdc++.h>
using namespace std;
vector<int> G[100001];
int visited[100001];
int level[100001],maxlevel=1;
vector<int> res;
void bfs(int v0)
{
queue<int> q;
q.push(v0);
visited[v0]=1;
int nowlevel=0;//表示当前所处层数
level[v0]=1;
while(!q.empty())
{
int tmp=q.front();
q.pop();
if(level[tmp]!=nowlevel)//若当前层数落伍了则更新当前层数,并把结果数组更新
{
nowlevel=level[tmp];
res.clear();
res.push_back(tmp);
}
else//否则,就一直往结果数组存顶点
{
res.push_back(tmp);
}
for(int i=0;i<G[tmp].size();i++)
{
if(visited[G[tmp][i]]!=1)
{
q.push(G[tmp][i]);
visited[G[tmp][i]]=1;
level[G[tmp][i]]=level[tmp]+1;
}
}
}
maxlevel=nowlevel;
return;
}
int main()
{
int N;
cin>>N;
int oldest=-1;
for(int i=1;i<=N;i++)
{
int parent;
scanf("%d",&parent);
if(parent==-1)
{
oldest=i;
continue;
}
G[parent].push_back(i);
}
bfs(oldest);
sort(res.begin(),res.end());
cout<<maxlevel<<endl;
for(int i=0;i<res.size();i++)
{
if(i>0)
{
putchar(' ');
}
printf("%d",res[i]);
}
}