E34 树形DP 树的中心
在树中,如果节点
u 作为根节点时,从
u 出发的最长链最短,那么称
u 为树的中心。
- 树的中心不一定唯一,但最多有 2 个,且这两个中心是相邻的。
- 树的中心一定位于树的直径上。
- 树上所有点到其最远点的路径一定交会于树的中心。
- 当树的中心为根节点时,其到达直径端点的两条链分别为最长链和次长链。
- 当通过在两棵树间连一条边以合并为一棵树时,连接两棵树的中心可以使新树的直径最小。
// 树的中心 树形DP O(n) #include<bits/stdc++.h> using namespace std; const int N=1000010; int n,son[N]; long long d1[N],d2[N],up[N],d[N],mxd=1e18; vector<pair<int,int>> e[N]; vector<int> v; void dfs(int x,int fa){ for(auto [y,w]:e[x]){ if(y==fa) continue; dfs(y,x); if(d1[x]<d1[y]+w) d2[x]=d1[x],d1[x]=d1[y]+w,son[x]=y; //d1[x]:x下方的最长距离 else if(d2[x]<d1[y]+w) d2[x]=d1[y]+w; //d2[x]:x下方的次长距离 } } void dfs2(int x,int fa){ for(auto [y,w]:e[x]){ if(y==fa) continue; if(y==son[x]) up[y]=max(up[x],d2[x])+w; else up[y]=max(up[x],d1[x])+w; //up[y]:y上方的最长距离 dfs2(y,x); } d[x]=max(up[x],d1[x]); //d[x]:到x的最长距离 mxd=min(mxd,d[x]); //最长距离的最小值 } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n; for(int i=1,a,b,c;i<n;i++){ cin>>a>>b>>c; e[a].emplace_back(b,c); e[b].emplace_back(a,c); } dfs(1,0); dfs2(1,0); for(int i=1;i<=n;i++) if(d[i]==mxd) v.emplace_back(i); for(int i:v) cout<<i<<"\n"; }
浙公网安备 33010602011771号