点分治——POJ 1741
写的第一道点分治的题目,权当认识点分治了。
点分治,就是对每条过某个点的路径进行考虑,若路径不经过此点,则可以对其子树进行考虑。
具体可以看menci的blog:点分治
来看一道例题:POJ 1741 Tree
题目大意:扔给你一颗有权无根树,求有多少条路径的长度小于k;
解题思路:先找出重心,用一次dfs处理出每个点到根的距离dis,然后将dis[]排序,用O(n)的复杂度处理出"过根且长度小于等于k的路径数目",删除根节点,对于每棵子树重复上述操作。
注意要去重:

像上面这样一个图,假设每条边的长度为1,即点到根的路径长等于点的深度,设k=4。此时dis[6]=2,dis[7]=2;dis[6]+dis[7]=4=k。但是当分治以③为根节点的子树时,dis[6]+dis[7]=2<k,这样6->7这条路径就被计算了两次,所以每次求完过根节点的符合条件的路径数之后,要减去在同一棵子树下的节点之间的符合条件的路径数。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; struct edge{
int to,next,w;
}e[]; int root,ans,u,v,l,n,kk,ne,size;
int head[],s[],d[],dis[],f[];
//s[k]为k的子节点数目,dis[k]为k到根节点的距离
bool b[]; void add(int a,int b,int c){
e[++ne].to=b; e[ne].w=c; e[ne].next=head[a]; head[a]=ne;
} void getroot(int k,int fa){
int v,i;
s[k]=;
f[k]=;
for(i=head[k];i!=-;i=e[i].next){
v=e[i].to;
if(v!=fa&&!b[v]){
getroot(v,k);
s[k]+=s[v];//递归求子节点数目
f[k]=max(f[k],s[v]);
}
}
f[k]=max(f[k],size-s[k]);//dp求重心
if(f[k]<f[root])root=k;
} void getdis(int k,int fa){
int i,v;
d[++d[]]=dis[k];//储存距离以便排序
for(i=head[k];i!=-;i=e[i].next){
v=e[i].to;
if(v!=fa&&!b[v]){
dis[v]=dis[k]+e[i].w;//dfs求距离
getdis(v,k);
}
}
} int clac(int k,int init){
int i,j,ret=;
d[]=;
dis[k]=init;
getdis(k,);
sort(d+,d++d[]);
for(i=,j=d[];i<j;)
if(d[i]+d[j]<=kk)ret+=j-i++;//计算路径数
else j--;
return ret;
} void work(int k){
int v,i;
ans+=clac(k,);//计算路径数并加在ans上
b[k]=true;//标记重心为删除
for(i=head[k];i!=-;i=e[i].next){
v=e[i].to;
if(!b[v]){
ans-=clac(v,e[i].w);//去重
f[]=size=s[v];
getroot(v,root=);//更新重心
work(root);//对子树求解
}
}
} int main(){
int i;
while(scanf("%d%d",&n,&kk)==){
if(n==&&kk==)break;
for(i=;i<=n;i++){
head[i]=-;
b[i]=;
}
ne=;
for(i=;i<=n-;i++){
scanf("%d%d%d",&u,&v,&l);
add(u,v,l);
add(v,u,l);//注意要连双向边
}
root=;
f[]=size=n;
getroot(,);//求重心
ans=;
work(root);
printf("%d\n",ans);
}
return ;
}
总体上感觉点分治不是很难理解,只要对题目有思路应该能写出来。(orz就是写代码经常出错!b[v]写成!b[k]之类的还查不出来)
点分治——POJ 1741的更多相关文章
- 树上点分治 poj 1741
Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dist(u,v ...
- 树分治 poj 1741
n k n个节点的一棵树 k是距离 求树上有几对点距离<=k; #include<stdio.h> #include<string.h> #include<algo ...
- 【POJ 1741】 Tree (树的点分治)
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 100 ...
- poj 1741 树的点分治(入门)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18205 Accepted: 5951 Description ...
- poj 1741 Tree(树的点分治)
poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...
- poj 1741 楼教主男人八题之中的一个:树分治
http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...
- POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量
POJ 1741. Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 34141 Accepted: 11420 ...
- 树的点分治 (poj 1741, 1655(树形dp))
poj 1655:http://poj.org/problem?id=1655 题意: 给无根树, 找出以一节点为根, 使节点最多的树,节点最少. 题解:一道树形dp,先dfs 标记 所有节点的子 ...
- POJ 1741 Tree 求树上路径小于k的点对个数)
POJ 174 ...
随机推荐
- SQL基础教程(第2版)第1章 数据库和SQL:练习题
CREATE TABLE Addressbook ( regist_no INTEGER NOT NULL, name ) NOT NULL, address ) NOT NULL, tel_no ) ...
- UML-状态机图和建模
1.目标:如何画状态机图 2.定义:描述某个对象的状态.感兴趣的事件.以及对象响应该事件的行为. 转换:用箭头表示 状态:用圆角矩形表示 事件:指的是一件值得注意的事情的发生.如:拿起电话. 当事件“ ...
- MySQL--mysql中You can’t specify target table for update in FROM clause错误解决方法
参考:http://www.jb51.net/article/60926.htm mysql中You can't specify target table for update in FROM cla ...
- shell中通过sed替换文件中路径
通常sed指令修改行内容时使用:sed -i " 9 s/^.*/"type in what you want modified!"/" 其中"typ ...
- JavaScript—面向对象 贪吃蛇_2 游戏对象
游戏对象 function Game(map) { this.map = map; this.food = new Food(this.map) this.snake = new Snake(this ...
- navicat for mysql连接数据库报错1251
使用Navicat for mysql 连接数据库,报如下错误 原因:数据库安装的是8.0版本,新的mysql采用了新的加密方式,导致连接失败 解决办法:数据库执行如下命令 改密码加密方式:用管理员身 ...
- python使用rsa非对称加密
1.安装rsa 支持python 2.7 或者 python 3.5 以上版本 使用豆瓣pypi源来安装rsa pip install -i https://pypi.douban.com/simpl ...
- c语言中常用的串运算
调用标准库函数 #include<string.h> 串比较,strcmp(char s1,char s2) 串复制,strcpy(char to,char from) 串连接,strca ...
- 复杂json解析方式[GsonFormat]
针对开发人员来讲,善于用工具,事半功倍. 干货: 1.IntelliJ IDEA 通过GsonFormat插件将JSONObject格式的String 解析成实体 插件地址:https://plugi ...
- IDEA中的常用插件安装以及使用的介绍
IDEA中的lombok插件安装以及各注解的详细介绍 Grep Console 当你密密麻麻一大片的日志,去查看起来,很容易看花眼:这个工具正好解决了这个痛点,可以说它就是 IDEA 自带 Conso ...