传送门:P3884 [JLOI2009]二叉树问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3884
题目求三个数字:二叉树深度、宽度和x,y之间的距离。
一. 深度
使用lca求最近公共祖先的时候(对lca不熟的可以看这篇文章http://t.csdn.cn/XZ1xl),会用到数组(这里姑且叫做dis数组)dis来记录每一个结点的深度,那么深度遍历一遍数组,就能得到最大深度了。
//求depth
int depth = 0;
int[] wi = new int[maxn];
for(int i=1;i<=n;i++) {
depth = Math.max(depth, dis[i]);
wi[dis[i]]++;
}
二. 宽度
可以注意到上面代码中有一行是wi[dis[i]]++;,没错,这个就是用来求宽度的,我们把每一个深度的结点的数量记录在数组里面,然后for循环遍历一遍就ok了,结合下面代码:
//求宽度
int width = 0;
for(int i=1;i<=n;i++)
width = Math.max(width, wi[i]);
三. 两结点之间的距离
根据题目的意思,两点之间距离 = 节点u到最近公共祖先的距离 * 2 + 节点v到最近公共祖先的距离,那么思路很明显了,lca后直接求解就行了。
int distance = (dis[x]-dis[father]) * 2 + (dis[y]-dis[father]);
完整代码:
import java.io.*;
import java.util.*;
public class Main {
static int maxn=101;
static int n, cnt;
static int[] vv = new int[maxn<<1], to = new int[maxn<<1];
static int[] he = new int[maxn];
static int[] fa = new int[maxn],dis = new int[maxn];
public static void main(String[] args) throws IOException {
n = nextInt();
for(int i=1;i<n;i++){
int u = nextInt();
int v = nextInt();
addEdge(u,v);
addEdge(v,u);
}
dfs(1,0);
//求depth
int depth = 0;
int[] wi = new int[maxn];
for(int i=1;i<=n;i++) {
depth = Math.max(depth, dis[i]);
wi[dis[i]]++;
}
//求宽度
int width = 0;
for(int i=1;i<=n;i++)
width = Math.max(width, wi[i]);
//求距离
int x = nextInt();
int y = nextInt();
int father = lca(x,y);
int distance = (dis[x]-dis[father]) * 2 + (dis[y]-dis[father]);
out.println(depth);
out.println(width);
out.println(distance);
out.close();
}
public static void dfs(int u,int father){
fa[u] = father;
dis[u] = dis[father] + 1;
for(int i=he[u];i>0;i=to[i]) {
if(vv[i] == father) continue;
dfs(vv[i], u);
}
}
public static int lca(int x,int y){
while(x != y) {
if (dis[x] >= dis[y])
x = fa[x];
else
y = fa[y];
}
return x;
}
public static void addEdge(int u,int v){
vv[++cnt] = v;
to[cnt] = he[u];
he[u] = cnt;
}
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
public static int nextInt() throws IOException{
in.nextToken();
return (int)in.nval;
}
public static String nextString() throws IOException {
in.nextToken();
return in.sval;
}
}