Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001). 
Define dist(u,v)=The min distance between node u and v. 
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k. 
Write a program that will count how many pairs which are valid for a given tree. 
            --by  POJ
http://poj.org/problem?id=1741


点分治的相关题目;
有关点分治的内容;
题目大意为查询树上最短距离不大于k的点对个数;
我们应用点分治的思路,
统计在完全在某子树内经过其重心的路径;
然后再递归分治下去;
统计方式采取,dfs出子树中,点到重心的距离,查找合法(dis(i)+dis(j)≤k)的组合;
如何查找合法的组合?
 sort(dis+,dis+num+);
r=num;
for(l=;l<=num,l<r;l++){
while(dis[l]+dis[r]>k&&l<r)
  r--;
ans+=r-l;
}

可以看出查找效率主要在排序上,反正很快;

但发现当两点在同一子树中且dis(i)+dis(j)≤k时,他们被计入答案,但他们的最短路径甚至不经过该重心;

于是把这些点用相似的方式查出再减去即可;

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct ss{
int next,to,w;
};
ss e[];
int first[],num;
int n,k,ans,size[],max_size[],vis[],dis[];
inline void Init();
inline void build(int ,int ,int );
inline void part_dfs(int );
inline void dfs_size(int ,int );
inline int dfs_root(int ,int ,int );
inline int chan_ans(int ,int );
inline void dfs_len(int ,int ,int );
inline void in(int &ans)
{
ans=;bool p=false;char ch=getchar();
while((ch>'' || ch<'')&&ch!='-') ch=getchar(); if(ch=='-') p=true,ch=getchar();
while(ch<=''&&ch>='') ans=ans*+ch-'',ch=getchar(); if(p) ans=-ans;
}
int main()
{
int i,j,u,v,w;
while(scanf("%d%d",&n,&k)==){
if(n==)
return ;
Init();
for(i=;i<=n-;i++){
in(u),in(v),in(w);
build(u,v,w);build(v,u,w);
}
part_dfs();
printf("%d\n",ans);
}
}
inline void Init(){
memset(vis,,sizeof(vis));
memset(first,,sizeof(first));
ans=;num=;
}
inline void build(int f,int t,int wi){
e[++num].next=first[f];first[f]=num;
e[num].to=t;e[num].w=wi;
}
inline void part_dfs(int now){
int root,i;
dfs_size(now,);
root=dfs_root(now,,now);
ans+=chan_ans(root,);
vis[root]=;
for(i=first[root];i;i=e[i].next)
if(!vis[e[i].to]){
ans-=chan_ans(e[i].to,e[i].w);
part_dfs(e[i].to);
}
}
inline void dfs_size(int now,int fa){
size[now]=;
for(int i=first[now];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa){
dfs_size(e[i].to,now);
size[now]+=size[e[i].to];
}
}
inline int dfs_root(int now,int fa,int r){
int i,root=-,wroot;
max_size[now]=size[r]-size[now];
for(i=first[now];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa){
if(size[e[i].to]>max_size[now])
max_size[now]=size[e[i].to];
wroot=dfs_root(e[i].to,now,r);
if(max_size[wroot]<max_size[root]||root==-)
root=wroot;
}
if(max_size[now]<max_size[root]||root==-)
root=now;
return root;
}
inline int chan_ans(int root,int dis1){
int l,r,ans=;
num=;
dfs_len(root,dis1,);
sort(dis+,dis+num+);
r=num;
for(l=;l<=num,l<r;l++){
while(dis[l]+dis[r]>k&&l<r)r--;
ans+=r-l;
}
return ans;
}
inline void dfs_len(int now,int d,int fa){
dis[++num]=d;
for(int i=first[now];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa)
dfs_len(e[i].to,d+e[i].w,now);
}
//点分治:
//dfs分治{
//对每个分支dfs(两遍)重心
//以重心为根dfs统计合法路径个数
//}分治重心的子树结构
//dis:一个不具有顺序的点到当前结构的重心的距离表
//vis[i]标记(染色)已到过的重心
//size[i]
//max_size[i]记录某点的最大子树大小;
//由于基于每个分支的dfs之间是跳着的(因为现在的重心未必是前重心的子节点),所以需要vis顺便截断某次dfs,防止跑出分支

祝AC

POJ P1741 Tree 解题报告的更多相关文章

  1. 【LeetCode】863. All Nodes Distance K in Binary Tree 解题报告(Python)

    [LeetCode]863. All Nodes Distance K in Binary Tree 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http ...

  2. 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)

    [LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...

  3. 【LeetCode】331. Verify Preorder Serialization of a Binary Tree 解题报告(Python)

    [LeetCode]331. Verify Preorder Serialization of a Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https:/ ...

  4. 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)

    [LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...

  5. 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  6. 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)

    [LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...

  7. 【LeetCode】662. Maximum Width of Binary Tree 解题报告(Python)

    [LeetCode]662. Maximum Width of Binary Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.co ...

  8. 【LeetCode】623. Add One Row to Tree 解题报告(Python)

    [LeetCode]623. Add One Row to Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problem ...

  9. POJ 2054 Color a Tree解题报告

    题干 Bob is very interested in the data structure of a tree. A tree is a directed graph in which a spe ...

随机推荐

  1. iOS几个功能:1.摇一摇;2.震动;3.简单的摇动动画;4.生成二维码图片;5.发送短信;6.播放网络音频等

    有一个开锁的功能,具体的需求就类似于微信的“摇一摇”功能:摇动手机,手机震动,手机上的锁的图片摇动一下,然后发送开锁指令.需求简单,但用到了许多方面的知识. 1.摇一摇 相对这是最简单的功能了. 在v ...

  2. 如何使用robots禁止各大搜索引擎爬虫爬取网站

    ps:由于公司网站配置的测试环境被百度爬虫抓取,干扰了线上正常环境的使用,刚好看到每次搜索淘宝时,都会有一句由于robots.txt文件存在限制指令无法提供内容描述,于是便去学习了一波 1.原来一般来 ...

  3. JVM调优总结 -Xms -Xmx -Xmn -Xss(转自:iteye unixboy)

    堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作 ...

  4. SDN定义网络

    http://edu.51cto.com/course/course_id-4466.html http://edu.51cto.com/course/course_id-4497.html

  5. vs2010和opencv2.4.9配置

    1.下载安装opencv2.4.9 直接到官网上下载opencv,我下载的是opencv2.4.9版本,然后进行安装,opencv的安装其实就是解压,我解压的路径是D:\opencv249.解压完成后 ...

  6. 【性能测试】:监控Mysql数据库方式

    1,  进入到/etc目录下,打开my.cnf文件,在文件最后添加几行 slow_query_log = ON                             //打开慢查询开关 slow_q ...

  7. 解决Visual C++ Redistributable for Visual Studio 2015的安装问题(摘录)

    1. Visual C++ Redistributable for Visual Studio 2015系统要求:Windows 7情况下必须是Windows 7 with SP1.或者Windows ...

  8. SpringMVC初写(二)映射类型、限制和数据绑定

    映射路径 a)映射路径的概述 所谓的映射路径,就是匹配请求路径和执行方法关系的路径 请求路径:http://localhost:8080/springmvc-demo-cofig/say.do 映射路 ...

  9. Mac 10.12安装StarUML

    说明:这款是收费软件,但是可以不缴费继续使用,然后就是有弹框提示收费而已.基本揽括了时序图.用例图.流程图等等.主要是跨平台且小巧. 下载: (链接: https://pan.baidu.com/s/ ...

  10. 开源前夕先给大家欣赏一下我用C语言开发的云贴吧 网站自动兼容-移动、手机、PC自动兼容云贴吧

    开源前夕先给大家欣赏一下我用C语言开发的移动.手机.PC自动兼容云贴吧 - 涨知识属马超懒散,属虎太倔强.十二生肖全了!-转自云寻觅贴吧 转: 涨知识属马超懒散,属虎太倔强.十二生肖全了! -转自云寻 ...