洛谷P3884 [JLOI2009]二叉树问题
Posted MN2016
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P3884 [JLOI2009]二叉树问题相关的知识,希望对你有一定的参考价值。
题目描述
如下图所示的一棵二叉树的深度、宽度及结点间距离分别为:
深度: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)倍增
分析:
看题看了很久都没看懂,后来才发现这个是一个几乎lca的模板问题,只用把路径处理一下就好了,这里采用倍增的算法。
上代码:
1 #include<cstdio> 2 #define max(a,b) a>b?a:b 3 #define swap(a,b) a^=b^=a^=b 4 #define maxn 110 5 using namespace std; 6 7 int n,m,s,tot,head[maxn],deep[maxn],p[maxn][20],md,t[10],ans; 8 struct node 9 { 10 int nxt,to; 11 }edge[maxn<<1]; 12 13 int read() 14 { 15 int x=0,f=1; 16 char c=getchar(); 17 while (c<48||c>57) 18 f=c==‘-‘?-1:1,c=getchar(); 19 while (c>=48&&c<=57) 20 x=(x<<1)+(x<<3)+(c^48),c=getchar(); 21 return x*f; 22 } 23 24 void add(int a,int b) 25 { 26 edge[++tot]=(node){head[a],b}; 27 head[a]=tot; 28 edge[++tot]=(node){head[b],a}; 29 head[b]=tot; 30 } 31 32 void init() 33 { 34 for (int j=1;(1<<j)<=n;j++) 35 for (int i=1;i<=n;i++) 36 if (p[i][j-1]) 37 p[i][j]=p[p[i][j-1]][j-1]; 38 } 39 40 int dfs(int u) 41 { 42 for (int i=head[u];i;i=edge[i].nxt) 43 if (!deep[edge[i].to]) 44 { 45 deep[edge[i].to]=deep[u]+1; 46 p[edge[i].to][0]=u; 47 dfs(edge[i].to); 48 } 49 } 50 51 int LCA(int a,int b) 52 { 53 if (deep[a]<deep[b]) 54 swap(a,b); 55 int i,j; 56 for (i=0;(1<<i)<=deep[a];i++); 57 i--; 58 for (j=i;j>=0;j--) 59 if (deep[b]<=deep[a]-(1<<j)) 60 a=p[a][j]; 61 if (a==b) 62 return a; 63 for (j=i;j>=0;j--) 64 if (p[a][j]!=p[b][j]&&deep[p[a][j]]>=1) 65 { 66 a=p[a][j]; 67 b=p[b][j]; 68 } 69 return p[a][0]; 70 } 71 72 int main() 73 { 74 int i,j,k,u,v; 75 n=read(); 76 for (i=1;i<=n-1;i++) 77 add(read(),read()); 78 u=read(),v=read(); 79 deep[1]=1; 80 dfs(1); 81 init(); 82 for (i=1;i<=n;i++) 83 md=max(md,deep[i]),t[deep[i]]++; 84 for (i=1;i<=9;i++) 85 t[0]=max(t[0],t[i]); 86 k=LCA(u,v); 87 ans=(deep[u]-deep[k])*2+deep[v]-deep[k]; 88 printf("%d\n%d\n%d",md,t[0],ans); 89 return 0; 90 }
以上是关于洛谷P3884 [JLOI2009]二叉树问题的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3884 [JLOI2009]二叉树问题 题解