1. 程式人生 > >PAT 7-7 小字輩 (25 分)

PAT 7-7 小字輩 (25 分)

小白入門不懂BFS(廣度優先搜尋)和DFS(深度優先搜尋),如果不懂請參考原作者這裡

-------------------------------https://blog.csdn.net/raphealguo/article/details/7523411--------------------------------------------------------

本題給定一個龐大家族的家譜,要請你給出最小一輩的名單。

輸入格式:

輸入在第一行給出家族人口總數 N(不超過 100 000 的正整數) —— 簡單起見,我們把家族成員從 1 到 N 編號。隨後第二行給出 N 個編號,其中第 i 個編號對應第 i 位成員的父/母。家譜中輩分最高的老祖宗對應的父/母編號為 -1。一行中的數字間以空格分隔。

輸出格式:

首先輸出最小的輩分(老祖宗的輩分為 1,以下逐級遞增)。然後在第二行按遞增順序輸出輩分最小的成員的編號。編號間以一個空格分隔,行首尾不得有多餘空格。

輸入樣例:

9
2 6 5 5 -1 5 6 4 7

輸出樣例:

4
1 9

最初思路:最開始有思路 如下圖,嘗試用vector寫,但是發現解決不了不斷搜尋的問題,如果非要去暴力搜尋,貌似超級麻煩;

這次收穫挺大,一直不懂bfs和dfs,這次也系統的看了一下,一會兒再去搞兩道練習一下;

圖1
圖2
圖3

最終思路:我的最初思路,和我的畫的圖都是沒問題的!看了一下網上大牛的解題方法,用到了圖的bfs(廣度優先搜尋),然後就學習了一下,還利用了佇列!

步驟:

1,我們把輸入的資料利用vector儲存,如圖,為我們後續步驟做基礎!在輸入期間標記老祖宗的下標(一開始就想到的) 

 2,我們建立一個數組,這個陣列的用處就是標記每個人的輩分,最終,利用這個輩分找到我們所要的最小輩分(數是最大值),這裡我們先把老祖宗的輩分設為1,即:int vv[100005];     vv[lzz]=1;

3, 我們先把老祖宗的下標入隊,看老祖宗這哥陣列有幾個元素,如圖2,利用向下搜尋。如圖3;並且不斷更新最小輩的值;

#include<iostream>
#include<vector>
#include<cstdio>
#include<set>
#include<map>
#include<string>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#include<ctype.h>
#include<stack>
#include<queue>
#include<list>
using namespace std;
vector<int>v[200005];
int vv[100005];
queue<int>q;
int main(){
    int n,x,lzz;//lzz 記錄老祖宗
    scanf("%d",&n);
    if(n==1){

    }
    for(int i=1; i<=n; i++){
        scanf("%d",&x);
        if(x==-1)
            lzz=i;
        else
            v[x].push_back(i);
    }
    if(n==1){
        printf("%d\n%d",1,1);
        return 0;
    }
    q.push(lzz);
    int bfen=1;        //統計輩分
    vv[lzz]=1;
    while(!q.empty()){
        int temp = q.front();
        q.pop();
        for(int i=0;i<v[temp].size();i++){
            vv[v[temp][i]] = vv[temp]+1;//更新每個人的輩分
            bfen = max(bfen,vv[v[temp][i]]);//更新(獲得)最小輩分的值
            q.push(v[temp][i]);//把下一次要遍歷的入隊
        }
    }
    printf("%d\n",bfen);
    int flag = 0;
    for(int i=1;i<=n;i++){
        if(vv[i]==bfen){
            if(!flag){
                printf("%d",i);
                flag = 1;
            }
            else
                printf(" %d",i);
        }
    }
}