【BZOJ】1468: Tree(POJ1741) 点分治
【题意】给定带边权树,求两点距离<=k的点对数。n<=40000。
【算法】点分治
【题解】对于一个区域,选择其重心x作为根,则划分出来的每棵子树都是子区域,可以证明至多划分log n次(通过vis[]划分区域)。每次划分所有点都扫描一次,所以仅遍历的复杂度是O(n log n)。
对于本题,将点x的所有子树节点dis处理出来后排序,然后用双指针法易得<=k的点对数。
但是,这样会把来自同一子树的路径也计算进去,需要减去。来自同一子树y的距离<=k的路径的数量等同于子树y内路径的距离+2*w<=k的路径的数量。
所以,设dis[y]=w后再减去子树y的路径数即可。
具体做法:calc(x,0)表示dis[x]=0统计得到的子树x内<=k的路径数,则ans(x)=calc(x,0)-calc(y,w),y=son[x],w是边(x,y)的权值。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
ll ans;
int root,first[maxn],tot,cnt,sz[maxn],sum,d[maxn],k,n;
bool vis[maxn];
struct edge{int v,w,from;}e[maxn*];
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void getroot(int x,int fa){
sz[x]=;
bool ok=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
getroot(e[i].v,x);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>sum/)ok=;
}
if(sum-sz[x]<=sum/&&ok)root=x;
}
void getdeep(int x,int fa,int w){
d[++cnt]=w;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v])getdeep(e[i].v,x,w+e[i].w);
}
ll calc(int x,int w){
cnt=;getdeep(x,,w);
sort(d+,d+cnt+);
int l=,r=cnt;
ll sum=;
while(l<r){
if(d[l]+d[r]<=k){sum+=r-l;l++;}
else r--;
}
return sum;
}
void solve(int x,int s){
ans+=calc(x,);vis[x]=;
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
ans-=calc(e[i].v,e[i].w);
if(sz[e[i].v]>sz[x])sum=s-sz[x];else sum=sz[e[i].v];
getroot(e[i].v,x);
solve(root,sum);
}
}
int main(){
scanf("%d",&n);
int u,v,w;
for(int i=;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
insert(u,v,w);insert(v,u,w);
}
scanf("%d",&k);
sum=n;
getroot(,);
ans=;
solve(root,n);
printf("%lld\n",ans);
return ;
}
【BZOJ】1468: Tree(POJ1741) 点分治的更多相关文章
- bzoj 1468 Tree(点分治模板)
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1527 Solved: 818[Submit][Status][Discuss] ...
- 【BZOJ】1468: Tree(点分治)
http://www.lydsy.com/JudgeOnline/problem.php?id=1468 分治真是一门高大上的东西... 好神... 树分治最好资料是:qzc的<分治算法在树的路 ...
- BZOJ.1468.Tree(点分治)
BZOJ1468 POJ1741 题意: 计算树上距离<=K的点对数 我们知道树上一条路径要么经过根节点,要么在同一棵子树中. 于是对一个点x我们可以这样统计: 计算出所有点到它的距离dep[] ...
- BZOJ 1468 Tree 【模板】树上点分治
#include<cstdio> #include<algorithm> #define N 50010 #define M 500010 #define rg registe ...
- BZOJ 1468: Tree
Description 真·树,问距离不大于 \(k\) 的点对个数. Sol 点分治. 同上. Code /********************************************* ...
- 【刷题】BZOJ 1468 Tree
Description 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K Input N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是 ...
- bzoj 1468 Tree 点分
Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1972 Solved: 1101[Submit][Status][Discuss] Desc ...
- 【POJ1741】Tree(点分治)
[POJ1741]Tree(点分治) 题面 Vjudge 题目大意: 求树中距离小于\(K\)的点对的数量 题解 完全不觉得点分治了.. 简直\(GG\),更别说动态点分治了... 于是来复习一下. ...
- hdu 4670 Cube number on a tree(点分治)
Cube number on a tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/ ...
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
随机推荐
- Spring的初始化:org.springframework.web.context.ContextLoaderListener
在web.xml中配置 <listener> <listener-class>org.springframework.web.context.ContextLoaderL ...
- EF 联合查询
EF 文章表和标签表联合查询标签id在dis中的文章,还不知道性能如何 var query = tagRepo.Entities.Include("Tags").Where(t = ...
- n元一维向量向左循环移位i的几种算法
1.最简单的算法借助于一个n元的中间向量在n步时间内完成 时间复杂度:O(n) 空间复杂度O(n) void shift_easy(int arr[], int _arr[], int n, int ...
- 【第九周】beta-review阶段贡献分分配
组名: 新蜂 组长: 武志远 组员: 宫成荣 谢孝淼 杨柳 李峤 项目名称: java俄罗斯方块NEO 武志远 武志远 武志远 武志远 武志远 宫成荣 宫成荣 杨柳 宫成荣 宫成荣 李峤 杨柳 李峤 ...
- break,continue,return 的区别
(1)break 跳出当前循环体 (2)continue 跳过当前循环体continue后面的代码,继续执行下一个循环 (3)return 和循环没关系,就是跳出该函数
- HttpHelper类及调用
首先列出HttpHelper类 /// <summary> /// Http操作类 /// </summary> public class HttpHelper { priva ...
- CIR,CBS,EBS,PIR,PBS 名词解释 令牌桶应用
为了达到上述目的,我们需要对进入网络的流量进行监督,实现CAR(Committed Access Rate). CAR:将进入网络的用户流量的速率限制在约定的范围之内,从而避免引起网络拥塞. CIR( ...
- 如何调整Flash与div的相互位置
让flash置于DIV层之下的方法,让flash不挡住飘浮层或下拉菜单,让Flash不档住浮动对象或层的关键参数:wmode=opaque. 方法如下: 针对IE 在<object>< ...
- jar包下载地址(fasterxml.jackson)
jar包下载地址(fasterxml.jackson) Home » com.fasterxml.jackson » core jar包下载地址 https://mvnrepository.com/a ...
- C++类间转换之dynamic_cast
当在C++的基类与派生类之间转换时,其多态性充分显现出来: 本次只讨论 dynamic_cast 的用法. 在查阅资料后发现百度百科关于 dynamic_cast (以及static_cast ...