[POJ1741]Tree(点分治)
树分治之点分治入门
所谓点分治,就是对于树针对点的分治处理
首先找出重心以保证时间复杂度
然后递归处理所有子树
对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况
- 路径过当前根
- 路径在子树中(递归处理)
那么关键就是如何计算第一种情况
设d[i]表示点i到当前根rt的距离,可以将d数组排序后线性复杂度求
然而此时会有些点对是在同一棵子树中,这些情况要减去
注意每次递归都要找一次重心以保证效率
这样复杂度就是O(nlog2n)
Code
#include <cstdio>
#include <algorithm>
#include <cstring>
#define Inf 0x7fffffff
#define N 10010
using namespace std; struct info{int to,nex,w;}e[N*2];
int n,k,tot,head[N],d[N],rt,Ans,sum,f[N],sz[N],dep[N];
bool vis[N]; void Link(int u,int v,int w){
e[++tot].nex=head[u];head[u]=tot;e[tot].to=v;e[tot].w=w;
} inline int read(){
int 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;
} void getrt(int u,int fa){
sz[u]=1,f[u]=0;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa||vis[v]) continue;
getrt(v,u);
sz[u]+=sz[v];
f[u]=max(f[u],sz[v]);
}
f[u]=max(f[u],sum-sz[u]);
if(f[rt]>f[u]) rt=u;
} void Init(){
tot=0,rt=0,Ans=0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
for(int i=1;i<n;++i){
int u=read(),v=read(),w=read();
Link(u,v,w),Link(v,u,w);
}
sum=n,f[0]=Inf;
getrt(1,0);
} void getdep(int u,int fa){
dep[++dep[0]]=d[u];
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v==fa||vis[v]) continue;
d[v]=d[u]+e[i].w;
getdep(v,u);
}
} int cal(int u,int cur){
d[u]=cur,dep[0]=0;
getdep(u,0);
sort(dep+1,dep+dep[0]+1);
int t=0;
for(int l=1,r=dep[0];l<r;)
if(dep[l]+dep[r]<=k) t+=r-l,++l;
else --r;
return t;
} void solve(int u){
Ans+=cal(u,0);
vis[u]=1;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(vis[v]) continue;
Ans-=cal(v,e[i].w);
sum=sz[v];
getrt(v,rt=0);
solve(rt);
}
} int main(){
while(~scanf("%d%d",&n,&k)&&n){
Init();
solve(rt);
printf("%d\n",Ans);
}
}
[POJ1741]Tree(点分治)的更多相关文章
- [poj1741]Tree(点分治+容斥原理)
题意:求树中点对距离<=k的无序点对个数. 解题关键:树上点分治,这个分治并没有传统分治的合并过程,只是分成各个小问题,并将各个小问题的答案相加即可,也就是每层的复杂度并不在合并的过程,是在每层 ...
- [bzoj1468][poj1741]Tree[点分治]
可以说是点分治第一题,之前那道的点分治只是模模糊糊,做完这道题感觉清楚了很多,点分治可以理解为每次树的重心(这样会把数分为若干棵子树,子树大小为log级别),然后统计包含重心的整个子树的值减去各个子树 ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- POJ1741 Tree + BZOJ1468 Tree 【点分治】
POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive ...
- POJ1741 Tree(树分治——点分治)题解
题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741 tree 【点分治】
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 25286 Accepted: 8421 Description ...
- POJ1741 Tree(树的点分治基础题)
Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v) ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
随机推荐
- codeforces 497E Subsequences Return
codeforces 497E Subsequences Return 想法 做完这题,学了一些东西. 1.求一个串不同子序列个数的两种方法.解一 解二 2.这道题 \(n\) 很大,很容易想到矩阵加 ...
- Mac版Mysql Workbench不展示Schema
Mac版的Mysql Workbench会不展示Schema,如下图 操作如下 cd ~/Library/Application\ Support/MySQL/Workbench/ rm wb_sta ...
- numpy初始化
一般的初始化就是用zeros这种去初始化,但你想测试一些函数的时候,如果是全0其实不好测试 可以先用python本身初始化一个list,然后转换成numpy的array a = [1.1,1.5,1. ...
- Dubbo实践(十六)集群容错
Dubbo作为一个分布式的服务治理框架,提供了集群部署,路由,软负载均衡及容错机制.下图描述了Dubbo调用过程中的对于集群,负载等的调用关系: 集群 Cluster 将Directory中的多个In ...
- BLE CC2541 串口BootLoader 即 SBL BootLoader 资料 收集
1.[CC254X_Bootloader]SBL(串口Bootloader)使用说明 2.CC2540协议栈高速串口通信解决(UART的DMA方式) 3.[BLE]CC2541之SBL 4.[BLE] ...
- 跟我一起学Linux-线程创建,类似FreeRTOS创建任务
1.参考学习大神网址:http://blog.csdn.net/ithomer/article/details/6063067 #include<stdio.h> #include< ...
- iOS 根据url生成二维码贴到底图上
根据url 生成指定尺寸的二维码图片 UIImage * createBinaryCodeImg(const char * url ,CGFloat size) { //create binary c ...
- Oracle 数据库备份和恢复配置
可能的失败及其解决方法 失败类型 我们坑你遇到的失败或错误分为两大类:物理和逻辑.物理错误一般是硬件错误或使用数据库的应用程序中的软件错误,而逻辑错误一般在终端用户级别(数据库用户和管理员). 按从轻 ...
- C++练习 | 递归判断二叉树是否同构
#include <iostream> using namespace std; struct Tree { int data; Tree *lchild; Tree *rchild; } ...
- JQuery弹出Dialog关闭方式close vs destroy
$editDialog.iDialog('close') $(this).dialog('close'); 等Close方法关闭Dialog时,Dialog并不是完全消失,只是隐藏起来.两个Dial ...