70分求调,后四个点不过,知道错哪里但是不理解
查看原帖
70分求调,后四个点不过,知道错哪里但是不理解
1081824
LoveFrieren楼主2024/8/10 19:44

思路就是求出直径,然后偏心距应该是路径端点到直径端点中较大的那一个,但是看题解说还有可能是不经过直径的距离最远的点,这一点不理解 注释部分是求直径中各点不经过直径的最远点的代码

#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;
} 
2024/8/10 19:44
加载中...