思路:先找出树的直径,然后在直径上尺取得到最终结果。
这个题数据很水,听说bzoj上有加强到1e5的数据,我是想过了洛谷的题之后在bzoj上试试的,但谁知没机会了。
上代码:
//#pragma GCC optimize (2)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
#include<vector>
#include<sstream>
#include<list>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn= 2e5+10;
const ll mod=6662333;
const int N=500;
struct node
{
int to,len,next;
} p[2*N];
int head[N];
int n,s;
int cnt;
void add(int from,int to,int len)
{
p[cnt].to=to;
p[cnt].len=len;
p[cnt].next=head[from];
head[from]=cnt++;
}
int vis[N];
struct L
{
int id,len;
};
int ans,maxl;
int bfs(int x)
{
L now;
queue<L>q;
now={x,0};
q.push(now);
ans=0,maxl=-1;
while(!q.empty())
{
now=q.front();q.pop();
vis[now.id]=1;
if(now.len>maxl)
{
ans=now.id;
maxl=now.len;
}
for(int i=head[now.id];i!=-1;i=p[i].next)
{
if(!vis[p[i].to])
q.push({p[i].to,now.len+p[i].len});
}
}
return ans;
}
int link[N];
int cntlink;
int flag=0;
void dfs(int s,int t)
{
link[++cntlink]=s;
if(flag)return;
if(s==t)
{
flag=1;
return ;
}
vis[s]=1;
for(int i=head[s];i!=-1;i=p[i].next)
{
if(!vis[p[i].to])
{
dfs(p[i].to,t);
if(flag)return;
cntlink--;
}
}
}
int maxL[N];
int pl[N];
int main()
{
cin>>n>>s;
int u,v,w;
memset(head,-1,sizeof head);
for(int i=0;i<n-1;i++)
{
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
memset(vis,0,sizeof vis);
u=bfs(1);
memset(vis,0,sizeof vis);
v=bfs(u);
memset(vis,0,sizeof vis);
dfs(u,v);
memset(vis,0,sizeof vis);
for(int i=1;i<=cntlink;i++)vis[link[i]]=1;
for(int i=1;i<=cntlink;i++)
{
bfs(link[i]);
maxL[i]=maxl;
}
pl[1]=0;
for(int i=1;i<=cntlink;i++)
for(int j=head[link[i]];j!=-1;j=p[j].next)
if(p[j].to==link[i+1])
{
pl[i+1]=p[j].len+pl[i];
break;
}
int fans=INF,l=1,r=1;
while(r<=cntlink)
{
while(l<r&&pl[r]-pl[l]>s)l++;
while(r+1<=cntlink&&pl[r+1]-pl[l]<=s)r++;
int tmp=0;
for(int i=1;i<l;i++)tmp=max(tmp,maxL[i]+pl[l]-pl[i]);
for(int i=l;i<=r;i++)tmp=max(tmp,maxL[i]);
for(int i=r+1;i<=cntlink;i++)tmp=max(tmp,maxL[i]+pl[i]-pl[r]);
fans=min(fans,tmp);
r++;
}
cout<<fans<<endl;
return 0;
}