点分治——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 ... 
随机推荐
- python刷LeetCode:5. 最长回文子串
			难度等级:中等 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab& ... 
- hadoop cmd
			一.hadoop文件操作 1.Ls hadoop fs -ls / 2.Put hadoop fs -put xx /path 3.Mkdir hadoop fs -mkdir 4.要从HDFS中删除 ... 
- Linux(CENTOS7) Redis安装
			1.下载redis 在disk目录下,输入以下命令进行下载: wget http://download.redis.io/releases/redis-2.8.3.tar.gz 2.解 ... 
- 剑指offer【08】- 二叉树的深度(java)
			题目:二叉树的深度 考点:知识迁移能力 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 牛客网上的剑指offer题, ... 
- 今天 运营同事发现的bug记录  上传商品时商品名称带双引号 导致输出页面时 双引号被转义
			例如 ”sk||““美白”淡化 这样输出表单页面时显示出来的只有sk|| 解决办法 把输出文字对双引号进行转义 
- bugs开发异常解决方法
			1. 前提 第一层:遇到异常首先必须告诉自己,冷静,不要慌.(一看到Bug就心慌,那么就不能释放必杀技) 2. 入门级 第二层:遇到Bug,第一潜意识看输出异常的信息的(控制台输出 ... 
- iTOP-4412-Ubuntu系统源码-ubuntu没有声音的解决办法
			准备工作 1.下载 vim 在命令行上输入 apt-get install vim 下载 vim 2.输入 vim /etc/hosts 在所打开界面的第一行最后写上 iTOP4412-ubuntu- ... 
- 吴裕雄--天生自然Linux操作系统:Linux 系统启动过程
			linux启动时我们会看到许多启动信息. Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段: 内核的引导. 运行 init. 系统初始化. 建立终端 . 用户登录系统. in ... 
- Java web之jsp,xml(2020.1.7)
			1.xml文档规则 xml声明 字符集 xml元素的基本规则: 合法标签名 嵌套子元素 空元素 
- MySql 相关面试题
			1.mysql 慢查询 目的:通过慢查询日志,记录超过指定时间的 SQL 语句,优化 sql 查询 步骤:查看慢查询开启状态-->设置慢查询 http://www.cnblogs.com/luy ... 
