调了一下午,最后只得了36分[汗],求大佬调一下,感激不尽
查看原帖
调了一下午,最后只得了36分[汗],求大佬调一下,感激不尽
579489
Vigilant_Yaksha楼主2022/10/9 15:11

思路:先用两遍DFS法求出直径,然后用双指针法求出"最小偏心距"。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iomanip>
#include<queue>
#include<list>
#include<math.h>
#include<cctype>
#include<map>
#include<stack>
#define maxn 100010
using namespace std;
typedef long long ll;
typedef unsigned long wf;
typedef unsigned int u32;
typedef unsigned long long u64;
int ans,n,s,far;
int dis[maxn],fa[maxn],flag[maxn];
struct edge{
	int to,w;
};
vector<edge> g[maxn];
void dfs(int now,int father){
	fa[now]=father;
	if(dis[now]>dis[far])far=now;
	for(int i=0;i<g[now].size();i++){
		int v=g[now][i].to,w=g[now][i].w;
		if(v==father||flag[v])continue;
		dis[v]=dis[now]+w;
		dfs(v,now);
	} 
}
int main(){
	cin>>n>>s;
	for(int i=1;i<n;i++){
		int u,v,w;
		cin>>u>>v>>w;
		g[u].push_back((edge){v,w});
		g[v].push_back((edge){u,w});  
	}
	int x,y;
	dis[1]=1;
	dfs(1,0);
	x=far;
	dis[far]=0;
	dfs(far,0);
	y=far;
	for(int i=y,j=y;i;i=fa[i]){
		while(dis[j]-dis[i]>s)
			j=fa[j];
		int maxx=max(dis[y]-dis[j],dis[i]);
		ans=min(ans,maxx);
	}
	for(int i=y;i!=0;i=fa[i])
		flag[i]=1;
	for(int i=y;i!=0;i=fa[i]){
		dis[i]=0;
		dfs(i,fa[i]);
	}
	for(int i=1;i<=n;i++)
		ans=max(ans,dis[i]);
	cout<<ans;
    return 0;
}
2022/10/9 15:11
加载中...