1.树的直径
https://www.luogu.com.cn/problem/B4016
//用树形dp解决
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5,M=2*N;
int n,f[N],ver[M],nex[M],head[M],tot,ans;
void add(int x,int y)
{
ver[++tot]=y;
nex[tot]=head[x],head[x]=tot;
}
void dfs(int u,int fa)
{
for(int i=head[u];i;i=nex[i])
{
int v=ver[i];
if(v==fa) continue;
dfs(v,u);
ans=max(ans,f[u]+f[v]+1);
f[u]=max(f[u],f[v]+1);
}
}
signed main()
{
cin>>n;
for(int i=1,x,y;i<n;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(1,-1);
cout<<ans<<endl;
return 0;
}
2.树的最近公共祖先(LCA)
https://www.luogu.com.cn/problem/P3379
倍增算法
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=5e5+5,M=2*N;
int ver[M],nex[M],head[M],tot;
int n,m,root;
int fa[N][31],cost[N][31],dep[N];
void add(int x,int y)
{
ver[++tot]=y;
nex[tot]=head[x],head[x]=tot;
}
void dfs(int u,int fat)
{
fa[u][0]=fat;
dep[u]=dep[fat]+1;
for(int i=1;i<31;i++)
{
fa[u][i]=fa[fa[u][i-1]][i-1];
}
for(int i=head[u];i;i=nex[i])
{
int v=ver[i];
if(v==fat) continue;
dfs(v,u);
}
}
int lca(int x,int y)
{
if(dep[x]>dep[y]) swap(x,y);
int tmp=dep[y]-dep[x],ans=0;
for(int j=0;tmp;j++,tmp>>=1)
if(tmp&1) y=fa[y][j];
if(y==x) return y;
for(int j=30;j>=0&&y!=x;j--)
{
if(fa[x][j]!=fa[y][j])
{
x=fa[x][j];
y=fa[y][j];
}
}
return fa[x][0];
}
void solve()
{
cin>>n>>m>>root;
for(int i=1,x,y;i<n;i++)
{
cin>>x>>y;
add(x,y);
add(y,x);
}
dfs(root,0);
while(m--)
{
int x,y;
cin>>x>>y;
cout<<lca(x,y)<<endl;
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T=1;
// cin>>T;
while(T--) solve();
return 0;
}
3.树的重心
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=3e5+5;
int n,q,ans[N],sz[N],we[N],fath[N];
vector<int> p[N];
void dfs(int u,int fa)
{
sz[u]=1;
we[u]=0;
ans[u]=u;
for(auto v:p[u])
{
if(v==fa) continue;
dfs(v,u);
sz[u]+=sz[v];
we[u]=max(we[u],sz[v]);
}
for(auto v:p[u])
{
int w=ans[v];
while(w!=u)
{
if(max(we[w],sz[u]-sz[w])<=sz[u]/2)
{
ans[u]=w;
break;
}
else w=fath[w];
}
}
}
void solve()
{
cin>>n>>q;
for(int i=2,u;i<=n;i++)
{
cin>>u;
fath[i]=u;
p[u].push_back(i);
}
dfs(1,-1);
while(q--)
{
int t;
cin>>t;
cout<<ans[t]<<endl;
}
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int T=1;
// cin>>T;
while(T--) solve();
return 0;
}