思路就是求出直径,然后偏心距应该是路径端点到直径端点中较大的那一个,但是看题解说还有可能是不经过直径的距离最远的点,这一点不理解 注释部分是求直径中各点不经过直径的最远点的代码
#include<bits/stdc++.h>
using namespace std;
const int M = 5e5 + 10;
int n, s, ans = M * 1000, far;
int dis[M], fa[M], flag[M];
struct edge{
int to, w;
};
vector<edge> G[M];
void dfs(int u, int f){
fa[u] = f;
if(dis[u] > dis[far]) far = u;
for(int i = 0; i < G[u].size(); ++i){
int v = G[u][i].to, w = G[u][i].w;
if(v == f || flag[v])continue;
dis[v] = dis[u] + w;
dfs(v, u);
}
}
int main(){
scanf("%d%d",&n, &s);
for(int i = 1, u, v, w; i < n; ++i){
scanf("%d%d%d", &u, &v, &w);
G[u].push_back((edge){v, w});
G[v].push_back((edge){u, w});
}
int A, B;
dis[1] = 0; dfs(1, 0); A = far;
dis[A] = 0; dfs(A, 0); B = far;
for(int i = B, j = B; i; i = fa[i]){
while(dis[j] - dis[i] > s)
j = fa[j];
int x = max(dis[B] - dis[j], dis[i]);
ans = min(ans, x);
}
// for(int i = B; i != 0; i = fa[i]) flag[i] = 1;
// for(int i = B; i != 0; i = fa[i]){
// dis[i] = 0;
// dfs(i, fa[i]);
// }
// for(int i = 1;i <= n; ++i)
// ans = max(ans, dis[i]);
printf("%d\n", ans);
return 0;
}