E33 树形DP 树的直径
树上任意两节点之间最长的简单路径即为树的直径。
- 一棵树可以有多条直径,他们的长度相等。
- 若树上所有边边权均为正,则树的所有直径中点重合。
// 树的直径 树形DP O(n) #include<bits/stdc++.h> using namespace std; const int N=500005; int n; long long f[N],g[N],md; vector<pair<int,int>> e[N]; void dfs(int u,int fa){ for(auto [v,w]:e[u]){ if(v==fa) continue; dfs(v,u); if(f[u]<f[v]+w) g[u]=f[u],f[u]=f[v]+w; //f[u]:从u向下走的最长距离 else if(g[u]<f[v]+w) g[u]=f[v]+w; //g[u]:从u向下走的次长距离 } md=max(md,f[u]+g[u]); //更新直径 } int main(){ ios::sync_with_stdio(0); cin>>n; for(int i=1,x,y,z;i<n;i++){ cin>>x>>y>>z; e[x].emplace_back(y,z); e[y].emplace_back(x,z); } dfs(1,0); cout<<md; }
// 树的直径 树形DP O(n) #include<bits/stdc++.h> using namespace std; const int N=500005; int n; long long d[N],md; vector<pair<int,int>> e[N]; void dfs(int u,int fa){ for(auto [v,w]:e[u]){ if(v==fa) continue; dfs(v,u); md=max(md,d[u]+w+d[v]); //拼凑直径 d[u]=max(d[u],d[v]+w); //d[u]:从u向下走的最长距离 } } int main(){ ios::sync_with_stdio(0); cin>>n; for(int i=1,x,y,z;i<n;i++){ cin>>x>>y>>z; e[x].emplace_back(y,z); e[y].emplace_back(x,z); } dfs(1,0); cout<<md; }
浙公网安备 33010602011771号