$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
思路:
1. d1[u] 表示从 u 往下走能到达的最大路径,d2[u] 表示从 u 往下走能到达的次大路径
2. p1[u] 表示从 u 出发的最大路径需要经过 u 的儿子节点 j,up[u] 表示从 u 往上走能到达的最大路径
3. j 往上走到父节点 u,从 u 可以往上走,也可以往下走不经过 j 的路径
4. 枚举所有点,找出该点能到达的最远距离 max(d1[u], up[u]) 的最小值
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 10010, M = N * 2, INF = 0x3f3f3f3f;
int n;
int h[N],e[M],ne[M],w[M],idx;
int d1[N],d2[N],p1[N],up[N];
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dfs_down(int u,int fa)
{
d1[u]=d2[u]=0;
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
int d=dfs_down(j,u)+w[i];
if(d>=d1[u]) //大于最大值
{
d2[u]=d1[u],d1[u]=d;
p1[u]=j;
}
else if(d>d2[u]) d2[u]=d; //仅大于次大值
}
return d1[u];
}
void dfs_up(int u,int fa)
{
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
if(j==fa) continue;
if(p1[u]==j) up[j]=max(up[u],d2[u])+w[i]; //父节点的最大路径经过当前点,则用次大路径比较
else up[j]=max(up[u],d1[u])+w[i]; //否则用最大路径比较
dfs_up(j,u);
}
}
int main()
{
cin>>n;
memset(h,-1,sizeof h);
for(int i=0;i<n-1;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
dfs_down(1,-1);
dfs_up(1,-1);
int res=INF;
for(int i=1;i<=n;i++) res=min(res,max(d1[i],up[i]));
cout<<res<<endl;
return 0;
}