[poj1741]Tree(点分治+容斥原理)
题意:求树中点对距离<=k的无序点对个数。
解题关键:树上点分治,这个分治并没有传统分治的合并过程,只是分成各个小问题,并将各个小问题的答案相加即可,也就是每层的复杂度并不在合并的过程,是在每层的处理过程。
此题维护的是树上路径,考虑点分治。
点分治的模板题,首先设点x到当前子树跟root的距离为,则满足${d_x} + {d_y} \le k$可以加进答案,但是注意如果x,y在同一棵子树中,就要删去对答案的贡献,因为x,y会在其所在的子树中在计算一次。同一棵子树中不必考虑是否在其同一棵子树中的问题,因为无论是否在他的同一棵子树,都会对他的父节点产生影响。而这些影响都是无意义的。
注意无根树转有根树的过程,需要选取树的重心防止复杂度从$O(n{\log ^2}n)$退化为$O({n^2})$
复杂度:$O(n{\log ^2}n)$
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#define inf 0x3f3f3f3f
#define maxn 10004
using namespace std;
typedef long long ll;
int head[maxn],cnt,n,k,ans,size,s[maxn],f[maxn],root,depth[maxn],num;//vis代表整体的访问情况,每个dfs不应该只用vis来存储
bool vis[maxn];
struct edge{
int to,w,nxt;
}e[maxn<<];
void add_edge(int u,int v,int w){
e[cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt++;
} inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
} void get_root(int u,int fa){//get_root会用到size
s[u]=;f[u]=;//f是dp数组
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa||vis[v]) continue;
get_root(v,u);
s[u]+=s[v];
f[u]=max(f[u],s[v]);
}
f[u]=max(f[u],size-s[u]);
root=f[root]>f[u]?u:root;
} void get_depth_size(int u,int fa,int dis){//同时获取size和depth
depth[num++]=dis;
s[u]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa||vis[v]) continue;
get_depth_size(v,u,dis+e[i].w);
s[u]+=s[v];
}
} int calc(int u,int fa,int w){
num=;
get_depth_size(u,fa,w);
sort(depth,depth+num);
int ret=;
for(int l=,r=num-;l<r;){
if(depth[l]+depth[r]<=k) ret+=r-l++;
else r--;
}
return ret;
} void work(int u){
vis[u]=true;
ans+=calc(u,-,);
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(vis[v]) continue;
ans-=calc(v,u,e[i].w);
size=s[v],root=;
get_root(v,u);
work(root);
}
} void init(){
memset(vis,false, sizeof vis);
memset(head,-,sizeof head);
ans=cnt=;
} int main(){
int a,b,c;
f[]=inf;
while(scanf("%d%d",&n,&k)&&(n||k)){
init();
for(int i=;i<n-;i++){
a=read(),b=read(),c=read();
add_edge(a,b,c);
add_edge(b,a,c);
}
size=n,root=;
get_root(,-);
work(root);
printf("%d\n",ans);
}
return ; }
[poj1741]Tree(点分治+容斥原理)的更多相关文章
- [POJ1741]Tree(点分治)
树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 ...
- [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]树上点分治
题意:给一个N个节点的带权树,求长度小于等于K的路径条数 思路:选取一个点作为根root,假设f(root)是当前树的答案,那么答案来源于两部分: (1)路径不经过root,那么就是完全在子树内,这部 ...
随机推荐
- liunx 安装工具总结
1 下载相关文件,比如hadoop 2 解压文件 tar -zxcf xxx.tar.gz 3 mv xxx 到指定目录:通常安装到/usr/local 或者自己建个目录 /usr/develo ...
- Jquery获取iframe中的元素
iframe与父页面之间相互获取元素的方法: 1.从父页面中获取iframe页面中的元素: 用法: $(window.frames["iframe_include_adverse" ...
- java.lang.NoSuchMethodError: org.jboss.logging.Logger.getMessageLogger(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
spring3_hibernate 集成报错信息 java.lang.NoSuchMethodError: org.jboss.logging.Logger.getMessageLogger(Ljav ...
- EasyNVR H5无插件摄像机直播解决方案前端解析之:引用videojs无法自动播放
关于videojs自动播放问题 播放流媒体多使用videojs来进行播放,videojs,本身自带自动播放属性: 通过添加autoplay(),来完成视频播放的自动加载: player = video ...
- 高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui
接上篇 接上篇<高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间> 本文围绕着实现EasyDSS高性能流 ...
- 校验时间冲突SQL写法
校验时间是否有冲突,时间是就是看两个时间断是否有交集(写法有两种): a.SELECT * FROM xxx WHERE (startTime > a AND startTime < b) ...
- 安装配置Django
安装配置Django 以下是基于python3.5 pip install Django 把python环境目录Scripts配置到环境变量,主要在命令行中随时可以使用django-admin 验证 ...
- 解决win7打印机共享出现“无法保存打印机设置(错误0x000006d9)的问题
最新解决win7打印机共享出现“无法保存打印机设置(错误0x000006d9)的问题,由系统下载吧率先分享: 有些用户在使用Windows7系统过程中,碰到到win7打印机共享出现“无法保存打印机设置 ...
- vue 组件与传值
一.表单输入绑定(v-model 指令) 可以用 v-model 指令在表单 <input>.<textarea> 及 <select> 元素上创建双向数据绑定. ...
- RK平台images打包细则【转】
本文转载自;https://blog.csdn.net/wangxueming/article/details/52808739 IMGs打包细节 平台: RK3288 背景: RK3288编译产生了 ...