POJ1741 Tree

这是一篇关于利用点分治算法解决在n个点的带权树上统计距离不超过k的点对数量的问题。文章介绍了算法的四步核心思路:找到树的重心、计算通过重心的点对、子树的去重处理以及递归解决子问题。通过排序和双指针技巧进行点对计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:n(n <= 10000)个点的带权树,统计距离<= k的点对个数。

分析:

第一道点分治...

1.求出树的重心。

2.统计通过重心的点对数量。

3.调用重心的每个儿子,去重。

4.删去重心,对每个子树递归求解。

至于统计,就是排序后,两个指针乱搞就行。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 10005, M = 20005;
int n,k,e,x,y,z,siz,mx,rt,ans,l,r,sz[N],v[N],d[N],dd[N],hd[N],w[M],nxt[M],to[M];
void add(int x, int y, int z) {to[++e] = y, w[e] = z, nxt[e] = hd[x], hd[x] = e;}

void dfs(int x, int p) {
	sz[x] = 1; int mxx = 0;
	for(int i=hd[x];i;i=nxt[i]) if(to[i]!=p&&!v[to[i]]) dfs(to[i],x),sz[x]+=sz[to[i]],mxx=max(mxx,sz[to[i]]);
	mxx = max(mxx, siz-sz[x]);
	if(mxx < mx) mx = mxx, rt = x;
}

void dfs2(int x, int p) {
	dd[e++] = d[x];
	for(int i=hd[x];i;i=nxt[i]) 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值