您的位置:首页 > 其它

【洛谷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;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: