【点分治】poj1741 Tree / poj2114 Boatherds / poj1987 Distance Statistics
三道题都很类似。给出1741的代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 10001
typedef pair<int,int> Point;
int n,K,ans;
int v[MAXN<<1],w[MAXN<<1],first[MAXN],next[MAXN<<1],en;
void AddEdge(const int &U,const int &V,const int &W)
{
v[++en]=V;
w[en]=W;
next[en]=first[U];
first[U]=en;
}
bool centroid[MAXN];//顶点是否已经作为重心删除的标记
int size[MAXN];//以该顶点为根的子树的大小
//计算子树的大小
int calc_sizes(int U,int Fa)
{
int res=1;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
res+=calc_sizes(v[i],U);
return size[U]=res;
}
//查找重心的递归函数,nn是整个子树的大小
//在以U为根的子树中寻找一个顶点,使得删除该顶点后得到的最大子树的顶点数最少
//返回值为(最大子树的顶点数,顶点编号)
Point calc_centroid(int U,int Fa,int nn)
{
Point res=make_pair(2147483647,-1);
int sum=1,maxv=0;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
{
res=min(res,calc_centroid(v[i],U,nn));
maxv=max(maxv,size[v[i]]);
sum+=size[v[i]];
}
maxv=max(maxv,nn-sum);
res=min(res,make_pair(maxv,U));
return res;
}
int td[MAXN],en2,ds[MAXN],en3;
//计算子树中所有顶点到重心的距离的递归函数
void calc_dis(int U,int Fa,int d)
{
td[en2++]=d;
for(int i=first[U];i;i=next[i])
if(v[i]!=Fa&&(!centroid[v[i]]))
calc_dis(v[i],U,d+w[i]);
}
int calc_pairs(int dis[],int En)
{
int res=0;
sort(dis,dis+En);
for(int i=0;i<En;++i)
res+=upper_bound(dis+i+1,dis+En,K-dis[i])-(dis+i+1);
return res;
}
void solve(int U)
{
calc_sizes(U,-1);
int s=calc_centroid(U,-1,size[U]).second;
centroid[s]=1;
//情况1:递归统计按重心s分割后的子树中的对数
for(int i=first[s];i;i=next[i])
if(!centroid[v[i]])
solve(v[i]);
//情况2:统计经过重心s的对数
en3=0; ds[en3++]=0;
for(int i=first[s];i;i=next[i])
if(!centroid[v[i]])
{
en2=0; calc_dis(v[i],s,w[i]);
ans-=calc_pairs(td,en2);//先把重复统计的部分(即情况1)减掉
memcpy(ds+en3,td,en2*sizeof(int)); en3+=en2;
}
ans+=calc_pairs(ds,en3);
centroid[s]=0;
}
void init()
{
memset(first,0,sizeof(first));
en=ans=0;
}
int main()
{
while(1)
{
scanf("%d%d",&n,&K);
if(!n&&!K) break;
init();
int a,b,c;
for(int i=1;i<n;++i)
{
scanf("%d%d%d",&a,&b,&c);
AddEdge(a,b,c); AddEdge(b,a,c);
}
solve(1);
printf("%d\n",ans);
}
return 0;
}
【点分治】poj1741 Tree / poj2114 Boatherds / poj1987 Distance Statistics的更多相关文章
- poj1987 Distance Statistics
普通dfs访问每个点对的复杂度是O(n^2)的,显然会超时. 考虑访问到当前子树的根节点时,统计所有经过根的点(u, v)满足: dist(u) + dist(v) <= maxd,并且 bel ...
- BZOJ1468: Tree & BZOJ3365: [Usaco2004 Feb]Distance Statistics 路程统计
[传送门:BZOJ1468&BZOJ3365] 简要题意: 给出一棵n个点的树,和每条边的边权,求出有多少个点对的距离<=k 题解: 点分治模板题 点分治的主要步骤: 1.首先选取一个点 ...
- POJ1741 Tree + BZOJ1468 Tree 【点分治】
POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- BZOJ_3365_[Usaco2004 Feb]Distance Statistics 路程统计&&POJ_1741_Tree_点分治
BZOJ_3365_[Usaco2004 Feb]Distance Statistics 路程统计&&POJ_1741_Tree_点分治 Description 在得知了自己农 ...
- P4169-CDQ分治/K-D tree(三维偏序)-天使玩偶
P4169-CDQ分治/K-D tree(三维偏序)-天使玩偶 这是一篇两种做法都有的题解 题外话 我写吐了-- 本着不看题解的原则,没写(不会)K-D tree,就写了个cdq分治的做法.下面是我的 ...
- POJ 1987 Distance Statistics 树分治
Distance Statistics Description Frustrated at the number of distance queries required to find a ...
- 洛谷P3806 点分治1 & POJ1741 Tree & CF161D Distance in Tree
正解:点分治 解题报告: 传送门1! 传送门2! 传送门3! 点分治板子有点多,,,分开写题解的话就显得很空旷,不写又不太好毕竟初学还是要多写下题解便于理解 于是灵巧发挥压行选手习惯,开始压题解(bu ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
随机推荐
- 关于session variables 和 global variables
背景 有同学问到这样一个问题:原来的binlog格式是statement,为什么执行了 set global binlog_format='row' 和 set binlog_format='row' ...
- Idea 怎么远程debug
注意的问题:远程debug别人的服务器只能开一个debug,所以当你的同事比你先远程debug同一台服务器时,你应该报Error running 某某ip地址 .unable to open debu ...
- DSP投放进阶指南
- AngularJs学习——实现列表内容项的增加删除
效果截图: 说明:引入bootstrap.min.css样式库和angular.min.js的静态资源库,实现列表内容的增加和删除操作. AngularJS代码: <script src=&qu ...
- Java并发(8)- 读写锁中的性能之王:StampedLock
在上一篇<你真的懂ReentrantReadWriteLock吗?>中我给大家留了一个引子,一个更高效同时可以避免写饥饿的读写锁---StampedLock.StampedLock实现了不 ...
- 【数据结构】bzoj1455罗马游戏
Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻 ...
- Spring - IoC(10): 生命周期
Spring 容器可以管理 singleton 作用域 Bean 的生命周期,容器能够跟踪 Bean 实例的创建.销毁.管理 Bean 生命周期行为主要有两个时机: 注入 Bean 的依赖关系之后 即 ...
- react+redux基础用法
在学react的是,发现一旦我们封装好了我们的组件,那么我们的项目就跟搭积木一样简单快速,可是我们发现了一个问题,在一个页面往往会嵌套很多的组件,子组件必须要通过父组件传递参数才能渲染出数据,我们回想 ...
- 【mysql优化】大数据量分页优化
limit 翻页原理 limit offset,N, 当offset非常大时, 效率极低, 原因是mysql并不是跳过offset行,然后单取N行, 而是取offset+N行,返回放弃前offset行 ...
- 如何使用SDK在Ubuntu设备(包括仿真器和桌面)上运用应用程序
简介 有三种运行通过SDK创建的应用程序的方式:在桌面上,在联网的Ubuntu设备上,以及在仿真器中.这些方式为互补性方式,因为各有优缺点.您首先将了解如何管理SDK的设备类型,以及哪一个类型用于测试 ...