【洛谷 3884】二叉树问题
题目描述
如下图所示的一棵二叉树的深度、宽度及结点间距离分别为:
深度:4 宽度:4(同一层最多结点个数)
结点间距离: ⑧→⑥为8 (3×2+2=8)
⑥→⑦为3 (1×2+1=3)
注:结点间距离的定义:由结点向根方向(上行方向)时的边数×2,
与由根向叶结点方向(下行方向)时的边数之和。
输入格式
输入文件第一行为一个整数n(1≤n≤100),表示二叉树结点个数。接下来的n-1行,表示从结点x到结点y(约定根结点为1),最后一行两个整数u、v,表示求从结点u到结点v的距离。
输出格式
三个数,每个数占一行,依次表示给定二叉树的深度、宽度及结点u到结点v间距离。
输入输出样例
输入 #1
10 1 2 1 3 2 4 2 5 3 6 3 7 5 8 5 9 6 10 8 6
输出 #1
4 4 8
题解:lca简单应用。(模板都蓝题为啥这是黄题!!!)
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<bits/stdc++.h> using namespace std; const int N=102; struct node{ int to; int next; }e[N*2]; int n,x,y,cnt,vis[N],head[N],f[N][22]; void add(int x,int y){ e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; } int d[N]; void dfs(int u,int fa){ d[u]=d[fa]+1; for(int i=0;i<=19;i++) f[u][i+1]=f[f[u][i]][i]; for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa) continue; f[v][0]=u; dfs(v,u); } } int lca(int x,int y){ if(d[x]<d[y]) swap(x,y); for(int i=20;i>=0;i--){ if(d[f[x][i]]>=d[y]) x=f[x][i]; if(x==y) return x; } for(int i=20;i>=0;i--) if(f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } return f[x][0]; } int ans1,ans2,ans3; int main(){ freopen("3884.in","r",stdin); freopen("3884.out","w",stdout); scanf("%d",&n); for(int i=1;i<n;i++){ scanf("%d %d",&x,&y); add(x,y); add(y,x); } dfs(1,0); scanf("%d %d",&x,&y); for(int i=1;i<=n;i++){ ans1=max(ans1,d[i]); vis[d[i]]++; } for(int i=1;i<=100;i++) ans2=max(ans2,vis[i]); ans3=(d[x]-d[lca(x,y)])*2+(d[y]-d[lca(x,y)]); printf("%d\n%d\n%d\n",ans1,ans2,ans3); return 0; }