解法:我们先用换根
d
p
dp
dp(直接树形
d
p
dp
dp也行,就是想秀一波换根
d
p
dp
dp)求出距离所有点最大距离最小的根
r
t
rt
rt,然后以
r
t
rt
rt为根树形
d
p
dp
dp求出每个点到最远的叶子节点距离
d
[
u
]
d[u]
d[u],定义
d
p
[
u
]
dp[u]
dp[u]为
d
[
u
]
+
d
i
s
t
(
u
,
f
a
t
h
e
r
[
u
]
)
d[u] + dist(u, father[u])
d[u]+dist(u,father[u]),我们找到
r
t
rt
rt所有儿子中
d
p
[
s
o
n
]
dp[son]
dp[son]最大的那两个,然后加入优先队列,每次出队都把该节点
d
p
[
s
o
n
]
dp[son]
dp[son]最大的儿子加入优先队列,直到出
k
−
1
k-1
k−1次队列,所有出队的节点就是我们要选择的链,然后统计答案即可。
#include<bits/stdc++.h>#define pi pair<int, int>#define mk make_pair
using namespace std;constint maxn =1e5+10;
vector<pi> G[maxn];
vector<int> suf[maxn];int d[maxn], f[maxn], mn =2e9, rt;voiddfs(int u,int fa){
d[u]=0;
f[u]= fa;for(auto tmp : G[u])if(tmp.first != fa){int v = tmp.first;dfs(v, u);
d[u]=max(d[u], d[v]+ tmp.second);}}voiddfs2(int u,int fa){
d[u]=0;for(auto tmp : G[u])
d[u]=max(d[u], d[tmp.first]+ tmp.second);if(d[u]< mn)
mn = d[u], rt = u;
suf[u].push_back(0);for(int i = G[u].size()-1; i >0; i--){
pi tmp = G[u][i];int val =max(suf[u].back(), d[tmp.first]+ tmp.second);
suf[u].push_back(val);}int mx =0;for(auto tmp : G[u]){
d[u]=max(mx, suf[u].back());
mx =max(mx, d[tmp.first]+ tmp.second);
suf[u].pop_back();if(tmp.first != fa)dfs2(tmp.first, u);}}
priority_queue<pi> q;intmain(){int n, k, u, v, w;scanf("%d%d",&n,&k);for(int i =1; i < n; i++){scanf("%d%d%d",&u,&v,&w);
G[u].push_back(mk(v, w));
G[v].push_back(mk(u, w));}dfs(1,0);dfs2(1,0);dfs(rt,0);if(k ==1)returnprintf("%d\n", d[rt]),0;
pi Mx =mk(0,0), Mx2 =mk(0,0), Mx3 =mk(0,0);for(auto tmp : G[rt]){int val = d[tmp.first]+ tmp.second;if(val > Mx.first)
Mx3 = Mx2, Mx2 = Mx, Mx =mk(val, tmp.first);elseif(val > Mx2.first)
Mx3 = Mx2, Mx2 =mk(val, tmp.first);elseif(val > Mx3.first)
Mx3 =mk(val, tmp.first);}
q.push(Mx);
q.push(Mx2);int ans = Mx3.first;for(int i =2; i <= k; i++){
u = q.top().second;
q.pop();
pi mx =mk(0,0), mx2 =mk(0,0);for(auto tmp : G[u])if(tmp.first != f[u]){int val = d[tmp.first]+ tmp.second;if(val > mx.first)
mx2 = mx, mx =mk(val, tmp.first);elseif(val > mx2.first)
mx2 =mk(val, tmp.first);}
ans =max(ans, mx2.first);
q.push(mx);}printf("%d\n",max(ans, q.top().first));}