【点分治】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 ...
随机推荐
- POJ2492:A Bug's Life(种类并查集)
A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 45757 Accepted: 14757 题 ...
- 在eclipse中从gitlab上面下载项目
(1)在eclipse中 import --git--uri--输入用户名密码,下载,这个时候是在本地建立了一个本地仓库 (2)把仓库中的项目导入到eclipse的工作空间中. (3)将所需要的项目转 ...
- socket编程 ------ BSD socket API
伯克利套接字(Berkeley sockets),也称为BSD Socket.伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信. BSD Socket的应用 ...
- 理解JWT(JSON Web Token)认证及python实践
原文:https://segmentfault.com/a/1190000010312468?utm_source=tag-newest 几种常用的认证机制 HTTP Basic Auth HTTP ...
- IOS 上传项目到github 终端操作
1.创建github账号 2.创建秘钥 3.Github配置秘钥 4.上传文件 复制保存网址 终端操作,如果没有ssh,自行安装 GitHub配置秘钥 克隆github上创建的项目 将自己的本地项目, ...
- linux编译动态库 fPIC作用
在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无关代码. ...
- js实现2048小游戏
这是学完javascript基础,编写的入门级web小游戏 游戏规则:在玩法规则也非常的简单,一开始方格内会出现2或者4等这两个小数字,玩家只需要上下左右其中一个方向来移动出现的数字,所有的数字就会想 ...
- 最适合初学者学习的idea教程
https://github.com/judasn/IntelliJ-IDEA-Tutorial
- 【Foreign】远行 [LCT]
远行 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 0 5 10 1 4 5 2 3 2 ...
- 谈数据中心SDN与NFV
看到一篇谈论SDN与NFV的文章,分析的还不错,贴过来方便自己后续查阅: http://network.chinabyte.com/175/13095675.shtml 论数据中心SDN与NFV技术关 ...