【PAT天梯】【L2-2 小字辈(左子右兄加强版)】(树,水题)
題干:
L2-2?小字輩(左子右兄加強版)?(25 分)
本題給定一個龐大家族的家譜,要請你給出最小一輩的名單。
需要注意的是,家族成員的輸入方式,是按照“Left-child Right-sibling”(左兒子 右兄弟)的格式
【敲黑板】sibling的意思是兄弟/姐妹,是親兄弟,不是“表兄弟”!2019年春季PAT中不認(rèn)識單詞sibling的孩紙請牢記……
注:本題是在浙江大學(xué)陳越老師的GPLT-2018決賽L2-2題目“小字輩”題意基礎(chǔ)上改編而成。
輸入格式:
輸入在第一行給出家族人口總數(shù) N(不超過 100 000 的正整數(shù)) —— 簡單起見,我們把家族成員從 1 到 N 編號。
隨后的N行,每行給出1名家族成員的編號以及他的親屬關(guān)系,格式為3個以空格間隔的整數(shù)A?B?C,
其中的A(范圍1~N)是1名家族成員編號(每行的編號必定各不相同)
B的范圍是0~N,當(dāng)B不為0,表示A有兒子B;
C的范圍是0~N,當(dāng)C不為0,表示A有兄弟C。
題目保證輸入是正確的,即:只有一個家族(沒有分離成家族群),且家族中只有一位老祖宗(老祖宗即:他不是任何其他人的兒子)
輸出格式:
首先輸出最小的輩分(老祖宗的輩分最大、數(shù)值為 1,子孫的輩分?jǐn)?shù)值逐級遞增1)。
然后在第二行按遞增順序輸出輩分最小的成員的編號。編號間以一個空格分隔,行首尾不得有多余空格。
輸入樣例1:
5 1 2 0 2 4 3 3 0 0 4 0 5 5 0 0輸出樣例1:
3 4 5輸入樣例2:
5 2 5 3 1 2 0 3 0 0 4 0 0 5 0 4輸出樣例2:
3 4 5解題報告:
? 首先用入度為0的特點找到根節(jié)點,然后遞歸維護每個節(jié)點的深度。最后按要求輸出就行了。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<set> #include<map> #include<cmath> #include<cstring> typedef long long ll; using namespace std; const int MAX = 2e5 + 6; int n; int no[MAX],son[MAX],bro[MAX]; pair<int,int> pr[MAX]; int dep[MAX]; bool bk[MAX]; int ans2[MAX]; void go(int rt) {if(pr[rt].first == 0 && pr[rt].second == 0) return ;if(pr[rt].first != 0) {dep[pr[rt].first] = dep[rt] + 1;go(pr[rt].first);}if(pr[rt].second != 0) {dep[pr[rt].second] = dep[rt] ;go(pr[rt].second);} } int main() {cin>>n;for(int i = 1; i<=n; i++) {scanf("%d%d%d",&no[i],&son[i],&bro[i]);pr[no[i]] = make_pair(son[i],bro[i]);bk[son[i]]=1;bk[bro[i]]=1;}int rt=1;for(int i = 1; i<=n; i++) {if(bk[i] == 0){rt = i;break;}}dep[rt] = 1;go(rt);int ans1 = 0;for(int i = 1; i<=n; i++) {ans1 = max(ans1,dep[i]);}int tot = 0;for(int i = 1; i<=n; i++) {if(dep[i] == ans1) {ans2[++tot] = i;}}sort(ans2+1,ans2+tot+1);printf("%d\n",ans1);for(int i = 1; i<=tot; i++) {printf("%d%c",ans2[i],i == tot ? '\n' : ' ');}return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【PAT天梯】【L2-2 小字辈(左子右兄加强版)】(树,水题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩家主动为《赛博朋克2077》开发Mod
- 下一篇: 【ZOJ - 3778】Talented