最长链
最長鏈
題目描述現給出一棵N個結點二叉樹,問這棵二叉樹中最長鏈的長度為多少,保證了1號結點為二叉樹的根。
輸入描述輸入的第1行為包含了一個正整數N,為這棵二叉樹的結點數,結點標號由1至N。
接下來N行,這N行中的第i行包含兩個正整數l[i], r[i],表示了結點i的左兒子與右兒子編號。如果l[i]為0,表示結點i沒有左兒子,同樣地,如果r[i]為0則表示沒有右兒子。
輸出描述輸出包括1個正整數,為這棵二叉樹的最長鏈長度。
樣例輸入5
2 3
4 5
0 6
0 0
0 0
樣例輸出4
數據范圍及提示【樣例說明】
4-2-1-3-6為這棵二叉樹中的一條最長鏈。
?
【數據規模】
對于10%的數據,有N≤10;
對于40%的數據,有N≤100;
對于50%的數據,有N≤1000;
對于60%的數據,有N≤10000;
對于100%的數據,有N≤100000,且保證了樹的深度不超過32768。
?
【提示】
關于二叉樹:
二叉樹的遞歸定義:二叉樹要么為空,要么由根結點,左子樹,右子樹組成。左子樹和右子樹分別是一棵二叉樹。
請注意,有根樹和二叉樹的三個主要差別:
1. 樹的結點個數至少為1,而二叉樹的結點個數可以為0;
2. 樹中結點的最大度數沒有限制,而二叉樹結點的最大度數為2;
3. 樹的結點無左、右之分,而二叉樹的結點有左、右之分。
關于最長鏈:
最長鏈為這棵二叉樹中一條最長的簡單路徑,即不經過重復結點的一條路徑。可以容易證明,二叉樹中最長鏈的起始、結束結點均為葉子結點。
#include<cstdio> #include <queue> using namespace std; struct node{int l,r,f,deep; }t[100002]; int head[100002],to[200002],next[3000002],len[100002]; bool f[100002]; int n,max1,maxn; queue<int> q; int max(int a,int b){return a>b?a:b;} void cz(int x){t[x].deep=t[t[x].f].deep+1;if(t[x].l) cz(t[x].l);if(t[x].r) cz(t[x].r); } int work(int x){f[x]=1;q.push(x);int p;len[x]=0; //bfs求最長鏈while(!q.empty()){p=head[x];while(p){if(!f[to[p]]){q.push(to[p]);len[to[p]]=len[x]+1;max1=max(max1,len[to[p]]);f[to[p]]=1; }p=next[p];}q.pop();x=q.front();} } int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&t[i].l,&t[i].r);if(t[i].l!=0){t[t[i].l].f=i;to[0]++;to[to[0]]=t[i].l;next[to[0]]=head[i];head[i]=to[0];to[0]++;to[to[0]]=i;next[to[0]]=head[t[i].l];head[t[i].l]=to[0];}if(t[i].r!=0){t[t[i].r].f=i;to[0]++;to[to[0]]=t[i].r;next[to[0]]=head[i];head[i]=to[0];to[0]++;to[to[0]]=i;next[to[0]]=head[t[i].r];head[t[i].r]=to[0];} //建立邊表 }cz(1);max1=0;for(int i=1;i<=n;i++) if(max1<t[i].deep){max1=t[i].deep;maxn=i;}//找最深節點;max1=0;work(maxn);printf("%d",max1);return 0; } View Code?
轉載于:https://www.cnblogs.com/qingang/p/5742821.html
總結
- 上一篇: STM32F407 CAN Contro
- 下一篇: spring-profile详解