关于点分治模板问个问题
  • 板块P4178 Tree
  • 楼主辰云
  • 当前回复10
  • 已保存回复10
  • 发布时间2022/7/14 10:23
  • 上次更新2023/10/27 20:27:36
查看原帖
关于点分治模板问个问题
399936
辰云楼主2022/7/14 10:23
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

struct Edge{
	int to,w;
	Edge(int v,int w):to(v),w(w){};
};
const int INF = 1e9;
vector<Edge> G[40004];
int n,rt,ans;
bool vis[40004];
int siz[40004],k;
int maxp[40004];
int Tsiz,cnt;
int d[40004];

void get_rt(int u,int fa){
	siz[u]=1;maxp[u]=0;
	for(auto e:G[u]){
		if(e.to==fa||vis[e.to])continue;
		get_rt(e.to,u);
		siz[u]+=siz[e.to];
		maxp[u]=max(maxp[u],siz[e.to]);
	}
	maxp[u]=max(maxp[u],Tsiz-siz[u]);
	if(maxp[u]<maxp[rt])rt=u;
}

void Dfs(int u,int D,int fa){
	d[++cnt]=D;
	for(auto e: G[u]){
		if(e.to==fa||vis[e.to])continue;
		Dfs(e.to,D+e.w,u);
	}
}

int calc(int u,int D){
	cnt=0;Dfs(u,D,0);
	sort(d+1,d+1+cnt);
	int s=0,l=1,r=cnt;
	for(;;++l){
		while(r>0&&d[l]+d[r]>k)r--;
		if(r<l)break;
		s+=r-l+1;
	}
	return s;
}

void DFS(int u){
	ans+=calc(u,0);vis[u]=1;
	for(auto e: G[u]){
		if(vis[e.to])continue;
		ans-=calc(e.to,e.w);
		rt=0;Tsiz=siz[e.to],get_rt(e.to,0);
		DFS(rt);
	}
}

int main(){
	n=read();
	for(int i=1;i<=n-1;i++){
		int u=read(),v=read(),w=read();
		G[u].push_back(Edge(v,w));
		G[v].push_back(Edge(u,w));
	}
	k=read();
	maxp[rt=0]=INF;Tsiz=n;get_rt(1,0);
	DFS(rt);
	printf("%d",ans-n);
	return 0;
}

为什么最后输出答案时需要ans-n呢?

2022/7/14 10:23
加载中...