rt,此题数据范围中1≤n≤3×105,但是测试数据放过了 O(n2) 的做法,故制造hack数据如下:
#include<iostream>
#include<cstdlib>
using namespace std;
const int N=3e5+10;
int zyh(int x){
if(x<0) return -x;
else return x;
}
int main(){
freopen("hack.in","w",stdout);
cout<<N<<" 114\n";
for(int i=1;i<N;i++){
cout<<i<<" "<<i+1<<" ";
while(true){
int t=zyh(rand());
if(1<=t&&t<=1000){
cout<<t<<endl;
break;
}
}
srand(rand());
}
}
#include<iostream>
#include<cstring>
#include<deque>
using namespace std;
const int INF=0x7fffffff;
const int N=5e6+10;
struct node{
int to,nxt,val;
}edge[N];
int head[N];
int cnt;
void add(int u,int v,int w){
edge[++cnt]={v,head[u],w};
head[u]=cnt;
}
int dis1[N],dis2[N],dis3[N],maxd[N],pos1,pos2,maxn;
void dfs1(int x,int last,int tv){
dis1[x]=dis1[last]+tv;
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last) dfs1(edge[i].to,x,edge[i].val);
}
}
void dfs2(int x,int last,int tv){
dis2[x]=dis2[last]+tv;
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last) dfs2(edge[i].to,x,edge[i].val);
}
}
bool is_d[N];
void dfs3(int x,int last){
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last&&!is_d[edge[i].to]){
dfs3(edge[i].to,x);
maxd[x]=max(maxd[x],maxd[edge[i].to]+edge[i].val);
}
}
}
int d[N],dv[N],lmx[N],rmx[N];
int tt;
void dfs4(int x,int last,int tv){
d[++tt]=x;
dv[tt]=tv;
for(int i=head[x];i!=-1;i=edge[i].nxt){
if(edge[i].to!=last&&is_d[edge[i].to]){
dfs4(edge[i].to,x,edge[i].val);
}
}
}
deque<int> q;
int n,s,ans=INF;
int main(){
// freopen("hack3.in","r",stdin);
// freopen("hack3.out","w",stdout);
memset(head,-1,sizeof(head));
ios::sync_with_stdio(false);
cin>>n>>s;
for(int i=1;i<n;i++){
int x,y,z;
cin>>x>>y>>z;
add(x,y,z);
add(y,x,z);
}
dfs1(1,0,0);
for(int i=1;i<=n;i++){
if(dis1[i]>dis1[pos1]) pos1=i;
}
dfs2(pos1,0,0);
for(int i=1;i<=n;i++){
if(dis2[i]>maxn){
pos2=i;
maxn=dis2[i];
}
}
dfs1(pos2,0,0);
for(int i=1;i<=n;i++){
if(dis1[i]+dis2[i]==maxn) is_d[i]=true;
}
for(int i=1;i<=n;i++){
if(is_d[i]) dfs3(i,0);
}
dfs4(pos1,0,0);
for(int i=1;i<=tt;i++){
lmx[i]=max(lmx[i-1]+dv[i],maxd[d[i]]);
}
for(int i=tt;i>0;i--){
rmx[i]=max(rmx[i+1]+dv[i+1],maxd[d[i]]);
}
for(int i=2;i<=tt;i++){
dv[i]+=dv[i-1];
}
int ft=1;
for(int i=1;i<=tt;i++){
while(!q.empty()&&dv[i]-dv[q.front()]>s) q.pop_front();
while(!q.empty()&&maxd[d[q.back()]]<maxd[d[i]]) q.pop_back();
while(dv[i]-dv[ft]>s) ft++;
q.push_back(i);
ans=min(ans,max(maxd[d[q.front()]],max(lmx[ft],rmx[i])));
}
cout<<ans;
return 0;
}
存放在题目U402569的附加文件中,亦可提交代码进行验证。