点分治 RE 0pts 求条
  • 板块P4178 Tree
  • 楼主封禁用户
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/23 14:55
  • 上次更新2024/3/23 15:28:30
查看原帖
点分治 RE 0pts 求条
714592
封禁用户楼主2024/3/23 14:55

rt,

#include<bits/stdc++.h>
using namespace std;
int n,k,u,v,w,ans,cnt,root,minn,dis[40005],sub[40005];
bool vis[40005];
vector< pair<int,int> > g[40005];
int findroot(int now,int fa,int tot){
	int maxn=0;
	sub[now]=1;
	for(pair<int,int> son:g[now]){
		v=son.first;
		if(v==fa||vis[v])continue;
		findroot(v,now,tot);
		sub[now]+=sub[v];
		maxn=max(maxn,sub[v]);
	}
	maxn=max(maxn,tot-sub[now]);
	if(minn>maxn){
		root=now;
		minn=maxn;
	}
}
void getdis(int now,int fa,int sum){
	dis[++cnt]=sum;
	for(pair<int,int> son:g[now]){
		v=son.first,w=son.second;
		if(v==fa||vis[v])continue;
		getdis(v,now,sum+w);
	}
}
void calc(int opt){
	sort(dis+1,dis+cnt+1);
	for(int i=cnt;i;i--)ans+=opt*(upper_bound(dis+1,dis+i,k-dis[i])-dis-1);
}
void solve(int now,int fa,int tot){
	root=now,minn=tot-1;
	findroot(now,fa,tot);
	cnt=0;
	getdis(root,0,0);
	calc(1);
	for(pair<int,int> son:g[root]){
		v=son.first,w=son.second;
		if(v==fa||vis[v])continue;
		cnt=0;
		getdis(v,root,w);
		calc(-1);
	}
	vis[root]=1;
	for(pair<int,int> son:g[root]){
		v=son.first;
		if(v==fa||vis[v])continue;
		solve(v,root,sub[v]);
	}
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		cin>>u>>v>>w;
		g[u].push_back(make_pair(v,w)),g[v].push_back(make_pair(u,w));
	}
	cin>>k;
	solve(1,0,n);
	cout<<ans;
}

开O2

不开O2

2024/3/23 14:55
加载中...