天梯L2 - 026小字辈

版权声明:欢迎大家评论和指出错误,互相交流,如有转载,请指明出处 https://blog.csdn.net/qq_38185591/article/details/79808794

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 ;
}

展开阅读全文

没有更多推荐了,返回首页