E33 树形DP 树的直径

E33 树形DP 树的直径_哔哩哔哩_bilibili

U81904 【模板】树的直径 - 洛谷

树上任意两节点之间最长的简单路径即为树的直径

  • 一棵树可以有多条直径,他们的长度相等。
  • 若树上所有边边权均为正,则树的所有直径中点重合。
// 树的直径 树形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;
}

 

树的直径 - OI Wiki

B4016 树的直径 - 洛谷

 

posted @ 2023-04-10 10:19  董晓  阅读(1037)  评论(3)    收藏  举报