L2-026. 小字辈
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。
输入格式:
输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。
输出格式:
首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。
输入样例:9 2 6 5 5 -1 5 6 4 7输出样例:
4 1 9
题意和功夫传人那个差不多,就是给你N个人的父亲是哪个,祖先的父亲用-1来表示,然后查询你辈分最小的是第几辈儿,并且输出那些辈分的人。
这种题dfs 和 bfs都可以的,因为N是1e6,所以用个vector把关系保存起来,然后我用的是bfs,从-1的那个点去搜一遍,再排序就可以了。
代码如下:
#include <bits/stdc++.h>
using namespace std;
vector < vector<int> > v;
queue<int>q;
struct node {
int id,beifen;
} fa[100020];
bool cmp(struct node a,struct node b) {
if(a.beifen == b.beifen)
return a.id < b.id;
return a.beifen > b.beifen;
}
int main() {
int y,n,cnt = 0,id = 0;
scanf("%d",&n);
v.resize(n + 2);
for(int i = 1; i <= n; i++) {
scanf("%d",&y);
if(y == -1) v[0].push_back(i),fa[i].beifen = 1;
else v[y].push_back(i);
}
q.push(0);
while(!q.empty()) {
int x = q.front();
q.pop();
for(int i = 0; i < v[x].size(); i++)
fa[v[x][i]].beifen = fa[x].beifen + 1,q.push(v[x][i]);
}
for(int i = 0; i <= n; i++)
fa[i].id = i;
sort(fa + 1,fa + n + 1,cmp);
cout << fa[1].beifen << endl;
id = fa[1].beifen;
for(int i = 1; i <= n; i++)
if(id == fa[i].beifen) cnt++;
else break;
for(int i = 1; i <= cnt; i++)
printf("%d%c",fa[i].id,i == cnt? '\n':' ');
return 0 ;
}