POJ1741 Tree(树的点分治基础题)
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.
Input
The last test case is followed by two zeros.
Output
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8
题意:
有一棵树,求满足x到y距离小于等于m的无序点对(x,y)的个数。
思路:
第一次写树上的乱搞系列。。。
对于此题,树上的分治。愚见如下。
假设有如图:
以root为根,点对(x,y)有四种情况。
- 先说第四种,第四种是D-B-A-root-I..-X(经过root),dis(D,X)>m,无效,此处不考虑了。
- 第一种:A-root-I,经过root,而且dis(A,I)<=m,有效,累加。
- 第二种:B-A-C,不经过root,但是dis(B,root)+dis(root,C)<=m,有效,累加。但是在当A为根时,点对(B,C)距离满足要求,肯定还会被算一次,所以此时需要减去儿子为根的某些部分。
- 第三种:D-B-A-C,不经过root,而且dis(D,root)+dis(root,C)>m,所以此处不累加。但是dis(B,A)+dis(A,C)<=m,当root下降到某点时会累加,这也是第二种需要减去的原因,防止累加两次。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 20010
using namespace std;
int m,head[N],to[N],len[N],next[N],cnt,sz[N];
int deep[N],root,vis[N],son[N],sn,d[N],tot,ans;
//son[]最大儿子树,sz[]子树。
//vis[]表示是否做为根使用过。
void add(int x,int y,int z)
{
to[++cnt]=y,len[cnt]=z,next[cnt]=head[x],head[x]=cnt;
}
void getroot(int u,int fa)
{
son[u]=,sz[u]=;
for(int i=head[u];i;i=next[i])
if(to[i]!=fa&&!vis[to[i]]){
getroot(to[i],u);sz[u]+=sz[to[i]];
son[u]=max(son[u],sz[to[i]]);
}
son[u]=max(son[u],sn-sz[u]);
if(son[root]>son[u]) root=u;
}
void getdeep(int x,int fa)
{
d[++tot]=deep[x];
for(in
t i=head[x];i;i=next[i])
if(to[i]!=fa&&!vis[to[i]])
deep[to[i]]=deep[x]+len[i],getdeep(to[i],x);
}
int calc(int x)
{
tot=,getdeep(x,),sort(d+,d+tot+);
int i=,j=tot,sum=;
while(i<j) { //保证了不重复
if(d[i]+d[j]<=m) sum+=j-i,i++ ; //d[]+d[]<m的个数。利用了双指针的思想
else j--;
}
return sum;
}
void dfs(int u)
{
deep[u]=;vis[u]=;ans+=calc(u);
for(int i=head[u];i;i=next[i])
if(!vis[to[i]]){
deep[to[i]]=len[i];ans-=calc(to[i]);//居然是抽屉原理。。。 细思极恐
sn=sz[to[i]];root=;getroot(to[i],);dfs(root);
}
}
int main()
{
int n,i,x,y,z;
while(~scanf("%d%d",&n,&m)&&(n||m)){
memset(head,,sizeof(head));
memset(vis,,sizeof(vis));
cnt=; ans=;
for(i=;i<n;i++){
scanf("%d%d%d",&x,&y,&z)
add(x,y,z);add(y,x,z);
}
root=; son[]=0x7fffffff; sn=n;
getroot(,); dfs(root);
printf("%d\n",ans);
}
return ;
}
POJ1741 Tree(树的点分治基础题)的更多相关文章
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- 【poj1741】Tree 树的点分治
题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- 【POJ 1741】 Tree (树的点分治)
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 100 ...
- poj1741_Tree(树的点分治入门题)
题目链接:poj1741_Tree 题意: 给你一颗n个节点的树,每条边有一个值,问有多少点对(u,v),满足u->v的最短路径小于k. 题解: 典型的树的分治,板子题. #include< ...
- POJ1741(SummerTrainingDay08-G 树的点分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 23380 Accepted: 7748 Description ...
随机推荐
- j2EE的web.xml详解
https://blog.csdn.net/changqing5818/article/details/49928231 https://www.cnblogs.com/ClassNotFoundEx ...
- css 坑记
1. div 内容超出 (做换行处理) 要注意 white-space属性的运用 设置 div width:100%;(或者固定值) 设置换行 word-break: break-all; 设置 ...
- 【HTML5开发系列】CSS3
选择器 属性 背景和边框 盒模型 布局 文本 动画 其他
- Python菜鸟之路:Python基础-类(2)——成员、成员修饰符、异常及其他
三大成员 在Python的面向对象中,主要包括三大成员:字段.方法.属性 字段 类成员的字段又可分为普通字段.静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,代码示例如下: ...
- thymeleaf基本应用
Thymeleaf是个XML/XHTML/HTML5模板引擎,可以用于Web与非Web应用. Thymeleaf的主要目标在于提供一种可被浏览器正确显示的.格式良好的模板创建方式,因此也可以用作静态建 ...
- android中handler和bundle有什么区别和联系 都是用来传递消息吗都是信息的载体吗
1.handler是消息处理者,通常重写Handler的handleMessage()方法,在方法中处理接收到的不同消息,例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Ha ...
- delete 和 truncate 的 区别
如果要清空表中的所有记录,可以使用下面的两种方法: DELETE FROM table1 TRUNCATE TABLE table1 以下 为之区别: 1)执行速度和灵活性 trunca ...
- python3里面的图片处理库 pillow
在python2下用pil,而在python3下可以安装pillow 功能,在图片上加上几个字 #coding: utf-8 myPath = "./" fontPath = &q ...
- 获取android模拟器的IP地址
http://blog.csdn.net/yjkwf/article/details/7244632 1.输入adb devices查看加载的设备 2.使用 adb -s [设备] [命令]执行命令 ...
- Python基础(1)_python介绍、简单运算符
Python执行一个程序分为三个阶段 阶段一:先启动python解释器 阶段二:python解释器把硬盘中的文件读入到内存中 阶段三:python解释器解释执行刚刚读入内存的代码 二.编程语言的分类: ...