DSU on Tree 60pts求调
查看原帖
DSU on Tree 60pts求调
243345
return20071007楼主2024/8/14 11:55
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e6+5;	
bool flag=0;
ll n, k, d[N], s[N], son[N], dis[N], l[N], r[N], cnt=0, back[N], ans=1000000000;
struct E{
	ll v;
	ll w;
};
vector <E> e[N];
map <ll, ll> dep; 
void dfsd(ll x, ll fa){
	ll ma=-1;
	l[x]=++cnt;
	back[cnt]=x;
	s[x]++;
	for(auto y:e[x]){
		if(y.v==fa) continue;
		d[y.v]=d[x]+1;//深度
		dis[y.v]=dis[x]+y.w;//到根的距离
		dfsd(y.v,x);
		if(s[y.v]>ma){
			ma=s[y.v];
			son[x]=y.v;
		}
		s[x]+=s[y.v];
	}
	r[x]=cnt;
	return; 
}
void dfs(ll x, ll fa){
	for(auto y:e[x]){
		if(y.v==fa||y.v==son[x]) continue;
		dfs(y.v,x);
		dep.clear();
	}
	if(son[x]) dfs(son[x],x);
	for(auto y:e[x]){
		if(y.v==fa||y.v==son[x]) continue;
		dfs(y.v,x);
		for(ll i=l[y.v]; i<=r[y.v]; i++){
			if(dep.count(2*dis[x]+k-dis[back[i]])){
				ans=min(ans,dep[2*dis[x]+k-dis[back[i]]]+d[back[i]]-2*d[x]);
			}
		}
		for(ll i=l[y.v]; i<=r[y.v]; i++){
			if(dep.count(dis[back[i]])){
				dep[dis[back[i]]]=min(d[back[i]],dep[dis[back[i]]]); 
			}
			else dep[dis[back[i]]]=d[back[i]];
		}
	}
	if(dep.count(dis[x]+k)) ans=min(ans,dep[dis[x]+k]-d[x]);
	if(dep.count(dis[x])) dep[dis[x]]=min(dep[dis[x]],d[x]);
	else dep[dis[x]]=d[x];
	return;
}
int main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	cin>>n>>k;
	for(ll i=1, u, v, w; i<n; i++){
		cin>>u>>v>>w;
		u++, v++;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	d[1]=0;
	dis[1]=0;
	dfsd(1,0);
	dfs(1,0);
	if(ans==1000000000){
		cout<<-1;
		return 0;
	}
	cout<<ans;
	return 0;
}
2024/8/14 11:55
加载中...