这道题听说是一道点分的题,但是我不太想写,而且确实不太会

所以呢就随手写了个类似树规的东西

先考虑一个节点的左右节点相互之间的贡献

为了防止转移次数过多 我们把递归的下一层的重儿子的set拿来直接用

只要打上一个所连边权值的标记,就可以用来给这一层用了

而对于其他节点的set里的元素,我们直接枚举放到这里面就可以了

然后每加入一个元素 就用lower_bound查询第一个和大于S的值

查看是否符合要求并与现在的答案比较一下 就可以处理完了

而对于一直往上的链的贡献 只要dfs一遍处理前缀边权和

然后用倍增找每个节点第一个符合要求的值更新答案就可以了

付大度大概介于nlogn到nlog2之间吧,有O2就跑得很快了

贴上代码

#include<bits/stdc++.h>
using namespace std;
set <int> tong[100005];
int root[100005],size[100005],head[100005],nxt[200005],to[200005];
int son[100005],flag[100005],edge[100005],w[200005],tot,depth[200005];
int s,ans=0x7fffffff,n,e,shu1,shu2,shu3,all,father[100005][21];
int minn(int x,int y)
{
	if(x<y) return x;
	return y;
}
void add(int x,int y,int z)
{
	to[++tot]=y;
	nxt[tot]=head[x];
	w[tot]=z;
	head[x]=tot;
}
void dfs(int x,int fa)
{
	size[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa) continue;
		dfs(y,x);
		size[x]+=size[y];
		if(size[y]>size[son[x]]) son[x]=y,edge[x]=i;
	}
}
void dp(int x,int fa)
{
	if(son[x]) 
	{
		dp(son[x],x);
		root[x]=root[son[x]];
		flag[x]=flag[son[x]]+w[edge[x]];
		tong[root[x]].insert(-flag[x]);
	}
	else 
	{
		root[x]=++all;
		tong[root[x]].insert(0);
	}
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa||y==son[x]) continue;
		dp(y,x);
		flag[y]+=w[i];
		for(set<int>::iterator it=tong[root[y]].begin(),ed=tong[root[y]].end();it!=ed;it++)
		{
			set<int>::iterator another=tong[root[x]].lower_bound(s-*it-flag[y]-flag[x]);
			int now=*another+*it+flag[x]+flag[y];
			if(now>=s&&now<=e)
			ans=minn(ans,now);
		}
		for(set<int>::iterator it=tong[root[y]].begin(),ed=tong[root[y]].end();it!=ed;it++)
		{
			tong[root[x]].insert(*it+flag[y]-flag[x]);
		}
	}
}
void go(int x,int fa)
{
	for(int i=1;i<=20;i++)
	father[x][i]=father[father[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa) continue;
		depth[y]=depth[x]+w[i];
		father[y][0]=x;
		go(y,x);
	}
}
void deal(int x)
{
	int now=0;
	for(int i=20;i>=0;i--)
	{
		if(now+depth[x]-depth[father[x][i]]<s) 
		{
			now+=depth[x]-depth[father[x][i]]; 
			x=father[x][i];
		}
	}
	now+=depth[x]-depth[father[x][0]];
	if(now>=s&&now<=e) ans=minn(ans,now);
}
int main()
{
	freopen("path.in","r",stdin);
	freopen("path.out","w",stdout);
	cin>>n>>s>>e;
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d%d%d",&shu1,&shu2,&shu3);
		add(shu1,shu2,shu3);
		add(shu2,shu1,shu3);
	}
	dfs(1,1);
	dp(1,1);
	go(1,1);
	for(int i=1;i<=n;i++)
	{
		deal(i);
	}
	if(ans==0x7fffffff)
	{
		cout<<-1;
	}
	else cout<<ans;
	return 0;
}
/*
5 4 6
1 2 3
1 3 2
2 4 30
3 5 30
*/