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