PAT甲級_1004(Counting Leaves)

1004 數葉子

家族等級關係通常用族譜樹表示。你的工作是統計那些沒有孩子的家庭成員數目。

輸入規範

每個輸入文件包含一個測試實例。每個用例的首行包含N和M,N表示樹中的結點個數(0<N<100),M指非葉結點的個數。然後下面有緊跟M行,每行的格式如下:
ID K ID[1] ID[2] ...ID[K]
ID是一個兩位的數字,表示一個非葉結點。K表示其孩子的數量。隨後是一個序列,序列中是用兩位數表示的該結點的孩子ID。爲了簡單起見,我們把根結點的ID固定爲01。
輸入以N爲0結束。此時,這個用例不做處理。

輸出規範

對於每個測試用例,你應該計算從根節點開始的每層的沒有孩子的家庭成員個數。數字必須在一行內輸出,且用空格分隔,在每行的結尾不能又多餘的空格。

對於測試樣例表示了一個只有兩個節點的樹,01是根節點,02是01節點的孩子。因此在根節點01層級,沒有葉子節點,在下一層級,有一個葉子節點(02)。所以我們在一行內輸出“0 1”

測試樣例輸入
2 1
01 1 02
測試樣例輸出
0 1
解題思路

就是建一顆數,計算每一層葉子節點個數。所以我們需要按層次遍歷整顆樹,而這時候用廣度優先搜索會更加方便按層次遍歷數。

AC代碼
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef pair<int, int> PP;
vector<int> vt[105];        //vt[i]保存i節點的所有孩子
int res[105];               //res[i]表示第i層的葉子節點數目
int bfs() {
    int cnt = 0;        //記錄層數,根節點在第0層
    queue<PP> que;      //節點隊列,保存一個數對,first表示節點編號,second表示層數
    que.push({1, 0});   //從根節點開始按層次遍歷
    while(!que.empty()) {   
        PP temp = que.front();  
        que.pop();      
        if(!vt[temp.first].size()){ //如果該節點沒有孩子,則證明是葉子節點
            res[temp.second]++;
        }else {
            for(int i = 0; i < vt[temp.first].size(); i++){     //壓入該節點的所有孩子節點,層數爲該層+1
                que.push({vt[temp.first][i], temp.second+1});
            }
            cnt = temp.second+1;    
        }
    }
    return cnt;
}
int main() {
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        int d, k;
        cin >> d >> k;
        for(int j = 0; j < k; j++) {
            int td;
            cin >> td;
            vt[d].push_back(td);    //壓入節點d的所有孩子
        }
    }
    //以上爲輸入處理部分
    int cnt = bfs() + 1;
     for(int i = 0; i < cnt-1; i++) {
         cout << res[i] << ' ';
     }
    cout << res[cnt-1] << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章