D47【模板】树的直径 B4016 树的直径
D47 树的直径 B4016 树的直径_哔哩哔哩_bilibili
方法1:两次DFS,仅正边权,能记录路径
方法2:树形DP,正负边权,不能记录路径
// 树的直径 正边权 两次DFS O(n) #include<bits/stdc++.h> using namespace std; const int N=100005; int n,rt,d[N]; vector<pair<int,int>> e[N]; void dfs(int u,int fa){ if(d[rt]<d[u]) rt=u; //记录最远点 for(auto [v,w]:e[u]){ if(v==fa) continue; d[v]=d[u]+w; //d[v]从根走到v的距离 dfs(v,u); } } int main(){ cin>>n; for(int i=1,x,y;i<n;i++){ cin>>x>>y; e[x].emplace_back(y,1); e[y].emplace_back(x,1); } dfs(1,0); //找出离1最远的点rt d[rt]=0; dfs(rt,0); //找出离rt最远的点 cout<<d[rt]; }
// 树的直径 正负边权 树形DP O(n) #include<bits/stdc++.h> using namespace std; const int N=100005; int n,md,f[N],g[N]; //f[u]/g[u] 从u向下走的最长/次长距离 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; else if(g[u]<f[v]+w) g[u]=f[v]+w; } md=max(md,f[u]+g[u]); } int main(){ cin>>n; for(int i=1,x,y;i<n;i++){ cin>>x>>y; e[x].emplace_back(y,1); e[y].emplace_back(x,1); } dfs(1,0); cout<<md; }
// 树的直径 正负边权 树形DP O(n) #include<bits/stdc++.h> using namespace std; const int N=100005; int n,mxd,d[N]; //d[u]从u点向下走的最长距离 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); mxd=max(mxd,d[u]+w+d[v]); //拼凑直径 d[u]=max(d[u],d[v]+w); //更新d[u] } } int main(){ cin>>n; for(int i=1,x,y;i<n;i++){ cin>>x>>y; e[x].emplace_back(y,1); e[y].emplace_back(x,1); } dfs(1,0); cout<<mxd; }
浙公网安备 33010602011771号