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

 

posted @ 2019-11-11 17:08  #Cookies#  阅读(186)  评论(0编辑  收藏  举报