最裸的树剖模板,用子节点数来判断的不严格重链,顺便带个LCA
#include<iostream>
#include<vector>
using namespace std;
vector<int> lin[500005];
int in[500005],size[500005],fa[500005],top[500005],ans,n,num;
int abs(int x)
{
return x>=0?x:-x;
}
void dfs1(int x,int pre)
{
in[x]=++num;
fa[x]=pre;
for (int i=0;i<lin[x].size();i++)
{
int nex=lin[x][i];
if (nex==pre) continue;
dfs1(nex,x);
}
size[x]=num-in[x]+1;
}
void dfs2(int x,int t)
{
in[x]=++num;
top[x]=t;
if (size[x]==1) return;
int msize=0,heavy=0;//一定要赋初始值!
for (int i=0;i<lin[x].size();i++)
{
int nex=lin[x][i];
if (nex==fa[x]) continue;
if (size[nex]>msize)
{
msize=size[nex];
heavy=nex;
}
}
dfs2(heavy,t);
for (int i=0;i<lin[x].size();i++)
{
int nex=lin[x][i];
if (nex==fa[x] || nex==heavy) continue;
dfs2(nex,nex);
}
}
void lca(int x,int y)
{
int dis=0;
while (top[x]!=top[y])
{
if (deep[top[x]]!=deep[top[y]])
{
dis+=in[x]-in[top[x]];
x=fa[top[x]];
}
else
{
dis+=in[y]-in[top[y]];
y=fa[top[y]];
}
}
dis+=abs(in[x]-in[y])+1;
return dis;
}
int main()
{
cin>>n;
for (int i=1;i<n;i++)
{
int a,b;
cin>>a>>b;
lin[a].push_back(b);
lin[b].push_back(a);
}
num=0; dfs1(1,0);
num=0; dfs2(1,1);
}