萌新第一次发帖询问,也不知道排版对不对....
我在最后一个测试点wa了,找了很久都没找到Bug
我先解释下我是怎么处理求u和v之间距离的:
一棵二叉树,首先看输入的两个结点是否相等,相等直接返回。
另一种情况就是u和v深度不同,就是说不在同一层,这时候就要看深度哪个大,为了保证u结点的深度始终是大于v的,所以我要对deep[u]<deep[v]的情况进行处理,就是进行swap交换
(可能你会疑惑为什么要判断两个结点的深度大小,而且还要进行swap交换,后面会解释)
前面的操作就保证了u的结点深度大于v了,就一直找u的父亲结点,直到u的深度等于v的深度,也就是说这时候u和v是在同一层了。
所以说swap操作就是因为我后面的操作只是对u进行,没有对v进行,所以要保证u是更深的那个结点。
通过前面的操作后u和v就是同一起跑线了,然后再同时一起向上找祖先结点,找到了共同的祖先就返回。
还有一种情况就是最开始时u和v结点的深度就是一样的,这时候就判断直接上一步的那个操作:就是一起找共同祖先
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 300+5;
int father[maxn], deep[maxn], width[maxn]; //父亲,深度,宽度
int n, maxdeep=1, maxwidth = 0;
int lca(int u, int v)
{
if(deep[u]<deep[v]) //若u的深度小于v的深度
swap(u, v);
//使得u和v在同一深度(层)
while(deep[u]!=deep[v]){
u = father[u];
}
if(u==v){
return v;
}
//共同找最近的祖先结点
while(father[u]!=father[v]){
u = father[u];
v = father[v];
}
return father[u];
}
int main(){
int u, v, i;
cin>>n;
deep[1] = 1;
width[1] = 1;
for(i=1;i<n;i++){
cin>>u>>v;
father[v] = u; //父结点就是u
deep[v] =deep[u] + 1; //孩子结点的深度就是父结点深度+1
width[deep[v]]++; //宽度也就是同一深度(层)最多结点个数
if(maxdeep<deep[v]){
maxdeep = deep[v]; //更新最大深度
}
}
//更新最大宽度
for(i=1;i<maxdeep;i++){
if(maxwidth<width[i]){
maxwidth = width[i];
}
}
cout<<maxdeep<<endl<<maxwidth<<endl;
//算结点u到结点v间距离
cin>>u>>v;
cout<<(deep[u]-deep[lca(u,v)])*2+deep[v]-deep[lca(u,v)];
return 0;
}