【洛谷P3884 [JLOI2009]】二叉树问题
2018-05-06 19:02
232 查看
题目描述
如下图所示的一棵二叉树的深度、宽度及结点间距离分别为:
深度: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的模板问题,只用把路径处理一下就好了,这里采用倍增的算法。
上代码:
#include<cstdio> #define max(a,b) a>b?a:b #define swap(a,b) a^=b^=a^=b #define maxn 110 using namespace std; int n,m,s,tot,head[maxn],deep[maxn],p[maxn][20],md,t[10],ans; struct node { int nxt,to; }edge[maxn<<1]; int read() { int x=0,f=1; char c=getchar(); while (c<48||c>57) f=c=='-'?-1:1,c=getchar(); while (c>=48&&c<=57) x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } void add(int a,int b) { edge[++tot]=(node){head[a],b}; head[a]=tot; edge[++tot]=(node){head[b],a}; head[b]=tot; } void init() { for (int j=1;(1<<j)<=n;j++) for (int i=1;i<=n;i++) if (p[i][j-1]) p[i][j]=p[p[i][j-1]][j-1]; } int dfs(int u) { for (int i=head[u];i;i=edge[i].nxt) if (!deep[edge[i].to]) { deep[edge[i].to]=deep[u]+1; p[edge[i].to][0]=u; dfs(edge[i].to); } } int LCA(int a,int b) { if (deep[a]<deep[b]) swap(a,b); int i,j; for (i=0;(1<<i)<=deep[a];i++); i--; for (j=i;j>=0;j--) if (deep[b]<=deep[a]-(1<<j)) a=p[a][j]; if (a==b) return a; for (j=i;j>=0;j--) if (p[a][j]!=p[b][j]&&deep[p[a][j]]>=1) { a=p[a][j]; b=p[b][j]; } return p[a][0]; } int main() { int i,j,k,u,v; n=read(); for (i=1;i<=n-1;i++) add(read(),read()); u=read(),v=read(); deep[1]=1; dfs(1); init(); for (i=1;i<=n;i++) md=max(md,deep[i]),t[deep[i]]++; for (i=1;i<=9;i++) t[0]=max(t[0],t[i]); k=LCA(u,v); ans=(deep[u]-deep[k])*2+deep[v]-deep[k]; printf("%d\n%d\n%d",md,t[0],ans); return 0; }
相关文章推荐
- [JLOI2009]二叉树问题
- 洛谷1996 约瑟夫问题
- 【洛谷】加分二叉树,P1040
- 【面试】基于二叉树层次遍历相关问题的求解
- 二叉树的前、中、后序遍历与重构问题
- C语言 数据结构之 二叉树 数据结构实验之二叉树七:叶子问题
- 这是我参考网上编写的一道数据结构关于二叉树求其子树是否指针或者线索,及其对应得值,但是我运行结果却是有点问题,希望高手帮指教下!
- [BZOJ3631][洛谷P3258][JLOI2014]松鼠的新家
- 创建二叉树来实现指路问题
- 洛谷1071 潜伏者 NOIP2009 字符串模拟
- 第十周项目3-利用二叉树遍历思想解决问题(3)求二叉树b的叶子节点个数
- 【CJOJ1494】【洛谷2756】飞行员配对方案问题
- 剑指Offer 二叉树相关问题
- Dropping Balls - UVa 679 简单二叉树问题
- (洛谷 1258)小车问题
- 二叉树问题(转载)
- 洛谷 P2764 LibreOJ 6002 最小路径覆盖问题
- 洛谷—— P2149 [SDOI2009]Elaxia的路线
- 二叉树问题全集OK
- 加分二叉树_洛谷1040_dp