Description

给一棵有n个节点的树,每条边都有一个长度(小于1001的正整数)。 
定义dist(u,v)=节点u到节点v的最短路距离。 
给出一个整数k,我们称顶点对(u,v)是合法的当且仅当dist(u,v)不大于k。 
写一个程序,对于给定的树,计算有多少对顶点对是合法的。

Input

输入包含多组数据。 
每组数据的第一行有两个整数N,K(N<=10000)。接下来N-1行每行有三个整数u,v,l,代表节点u和v之间有一条长度l的无向边。 
输入结束标志为N=K=0.

Output

对每组数据输出一行一个正整数,即合法顶点对的数量。

Sample Input

5 4 
1 2 3 
1 3 1 
1 4 2 
3 5 1 
0 0

Sample Output

8

树分治裸题:

每一次找到树的重心,使得二分复杂度降为logn,然后每一个小区间做相同处理:

设 dis[i]表示到当前根节点X的距离 找到以当前节点X为根的满足dis[i]+dis[j]<=k的所有方案。

在统计的时候可能存在把同一子树满足dis[i]+dis[j]<=k的也统计进答案中,产生重复方案。

于是我们要减去每一棵子树中满足dis[i]+dis[j]<=k的方案。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; int n,k; int gi()
{
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=str*+ch-'',ch=getchar();
return str;
} const int N=;int sum=;int ans=;
int num=,head[N];int root=;int son[N];int f[N]={};bool vis[N];int dis[N];
int b[N];
struct Lin
{
int next,to,dis;
}a[N*]; void init(int x,int y,int z)
{
a[++num].next=head[x];
a[num].to=y;
a[num].dis=z;
head[x]=num;
} void getroot(int x,int last)
{
son[x]=;f[x]=;
int u;
for(int i=head[x]; i ;i=a[i].next)
{
u=a[i].to;
if(u==last || vis[u])continue;
getroot(u,x);
son[x]+=son[u];
f[x]=max(f[x],son[u]);
}
f[x]=max(f[x],sum-son[x]);
if(f[x]<f[root])root=x;
return ;
} void getdis(int x,int last)
{
int u;
b[++b[]]=dis[x];
for(int i=head[x];i;i=a[i].next)
{
u=a[i].to;
if(u==last || vis[u])continue;
dis[u]=dis[x]+a[i].dis;
getdis(u,x);
}
return ;
} int cal(int x,int dd)
{
int tot=,u;dis[x]=dd;
b[]=;
getdis(x,);
sort(b+,b+b[]+);
int l=,r=b[];
while(l<r)
{
if(b[l]+b[r]<=k)tot+=r-l,l++;
else r--;
}
return tot;
} void work(int x)
{
ans+=cal(x,);
vis[x]=;
int u;
for(int i=head[x];i;i=a[i].next)
{
u=a[i].to;
if(vis[u])continue;
ans-=cal(u,a[i].dis);
root=;sum=son[u];
getroot(u,x);
work(root);
}
return ;
} void Clear()
{
memset(vis,,sizeof(vis));
f[]=;
memset(a,,sizeof(a));
memset(head,,sizeof(head));
memset(dis,,sizeof(dis));
num=;
}
int main()
{
while(scanf("%d%d",&n,&k))
{
if(!n && !k)return ;
int x,y,z;
Clear();
for(int i=;i<=n-;i++)
{
x=gi();y=gi();z=gi();
init(x,y,z);init(y,x,z);
}
sum=n;
ans=;
root=;
getroot(,);
work(root);
printf("%d\n",ans);
}
return ;
}

[POJ1741]树上的点对 树分治的更多相关文章

  1. 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分

    树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...

  2. POJ1741:Tree——题解+树分治简要讲解

    http://poj.org/problem?id=1741 题目大意:给一棵树,求点对间距离<=k的个数. ———————————————————— 以这道题为例记录一下对于树分治的理解. 树 ...

  3. POJ1741 经典树分治

    题意:有一棵树,每条边有一个距离,求dis(u,v)<=k的点的对数 题解:树分治,对于一颗树上的两点,要么在同一颗子树上,要么在不同子树上,要么一个点是根,另一个在某一子树上,对于第一种情况我 ...

  4. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  5. 树分治&树链剖分相关题目讨论

    预备知识 树分治,树链剖分   poj1741 •一棵有n个节点的树,节点之间的边有长度.方方方想知道,有多少个点对距离不超过m 题解 点分治模板题.详见我早上写的http://www.cnblogs ...

  6. 树分治learning

    学习了树的点分治,树的边分治似乎因为复杂度过高而并不出众,于是没学 自己总结了一下 有些时候面对一些树上的结构 并且解决的是和路径有关的问题的时候 如果是多个询问 关注点在每次给出两个点,求一些关于这 ...

  7. UVALive 7148 LRIP【树分治+线段树】

    题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...

  8. COJ 0970 WZJ的数据结构(负三十)树分治

    WZJ的数据结构(负三十) 难度级别:D: 运行时间限制:1000ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 给你一棵N个点的无根树,点和边上均有权值.请你设计 ...

  9. Poj1741-Tree(树分治)

    题意:找树上有多少对距离小于K的对数解析:树分治模板题,见注释 代码 #include<cstdio> #include<cstring> #include<string ...

随机推荐

  1. Scala 集合入门

    1. 数组 1.1 定长数组 scala.Array 是定长的可变的索引型集合, JVM 中, Scala 的 Array 是以 Java 数组方式实现. String 对应 java.lang.St ...

  2. JAVA_SE基础——68.RunTime类

    RunTime类代表Java程序的运行时环境,每一个Java程序都有一个与之对应的Runtime实例,应用程序通过该对象与运行时环境相连,应用程序不能创建自己的Runtime实例,但可以通过getRu ...

  3. vue+mint-ui的微博页面(支持评论@添加表情等)

    github地址 https://github.com/KyrieZbw/Sneakers (如果觉得不错就给个小星星) 预览地址 页面展示 技术栈 vue2 + vuex + vue-router ...

  4. vue-入门

    数据绑定   <!--步骤1:创建html文件--> <!DOCTYPE html> <html lang="en"> <head> ...

  5. Mego开发文档 - 建模高级主题

    建模高级主题 在建模过程中我们还有许多其他情况,这里列出本框架中的有用特性来用于解决此类问题. 函数映射 我们可以将指定的CLR函数映射到数据库中的系统函数或自定义函数,该特性用于补充框架中未提供的数 ...

  6. angular2 学习笔记 ( angular cli & npm version manage npm 版本管理 )

    更新 : 2017-05-05 现在流行 Yarn ! 它是 facebook google 推出的东西. 算是补助 npm 做的不够好的地方. 源码依然是发布去 npm,只是下载接口换掉罢了哦. n ...

  7. 开发技巧(3-1)Eclipse查找关键字

    1.选择资源目录->选择search-file菜单 2.在弹出的对话框中, 输入要[搜索的字符串],选择[selected resources],点击[search]按钮 3.搜索结果

  8. python 迭代器 生成器

    迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  9. Help Jimmy ~poj-1661 基础DP

    Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落, ...

  10. Python:使用youtube-dl+ffmpeg+FQ软件下载youtube视频

    声明:本文所述内容都是从http://blog.csdn.net/u011475134/article/details/71023612博文中学习而来. 背景: 一同学想通过FQ软件下载一些youtu ...