Tree
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 18205   Accepted: 5951

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. 

Input

The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l. 
The last test case is followed by two zeros. 

Output

For each test case output the answer on a single line.

Sample Input

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

Sample Output

8
/*
poj 1741 树的点分治(入门) problem:
给一棵边带权树,问两点之间的距离小于等于K的点对有多少个 solve:
随便找的博客学习下
大致思路,对当前树先求其重心为根节点,然后找出所有点到根节点的距离. 然后就能计算出有多少的的和
<= k. 但是这两个点有可能来自同一个子树,所以在后面计算中减去,就能计算出过当前根节点的所有对.
以同样的方法计算子树的情况,递推下去就行.
重心是为了让最大子树的节点数最小,从而增加效率.
(个人理解)
hhh-2016-08-22 20:00:18
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
#define inf 0x3FFFFFFFFFFFFFFFLL
using namespace std;
const int maxn = 100010; struct node
{
int to,w;
node() {};
node(int v,int _w):to(v),w(_w) {};
}; vector<node> q[maxn];
int n,k,s[maxn],f[maxn],root,d[maxn],ans,limit;
int Size;
bool vis[maxn];
vector<int> ta; void get_root(int now,int fa)
{
int v;
s[now] = 1,f[now] = 0;
for(int i = 0;i < q[now].size();i++)
{
if( (v=q[now][i].to) == fa || vis[v])
continue;
get_root(v,now);
s[now] += s[v];
f[now] = max(f[now],s[v]);
}
f[now] = max(f[now],Size - s[now]);
if(f[now] < f[root]) root = now;
} void dfs(int now,int fa)
{
int v;
ta.push_back(d[now]);
s[now] = 1;
for(int i = 0;i < q[now].size();i++)
{
if( (v=q[now][i].to) == fa || vis[v])
continue;
d[v] = d[now] + q[now][i].w;
dfs(v,now);
s[now] += s[v];
}
} int cal(int now,int begi)
{
ta.clear(),d[now] = begi;
dfs(now,0);
sort(ta.begin(),ta.end());
int cnt = 0;
for(int l = 0,r=ta.size()-1;l<r;)
{
if(ta[l] + ta[r] <= limit) cnt += (r-l++);
else r --;
}
return cnt;
} void work(int now)
{
int v;
ans += cal(now,0);
vis[now] = 1;
for(int i = 0;i < q[now].size(); i++)
{
if(!vis[v = q[now][i].to])
{
ans -= cal(v,q[now][i].w);
f[0] = Size = s[v];
get_root(v,root = 0);
work(root);
}
}
} int main()
{
while(scanf("%d%d",&n,&limit) == 2)
{
if(!n && !limit)
break;
for(int i = 0;i <= n;i++) q[i].clear();
memset(vis,0,sizeof(vis)); int a,b,c;
for(int i = 1;i < n;i++)
{
scanf("%d%d%d",&a,&b,&c);
q[a].push_back(node(b,c));
q[b].push_back(node(a,c));
}
f[0] = Size = n;
get_root(1,root = 0);
ans = 0;
work(root);
printf("%d\n",ans);
}
return 0;
}

  

poj 1741 树的点分治(入门)的更多相关文章

  1. POJ 1741 树的点分治

    题目大意: 树上找到有多少条路径的边权值和>=k 这里在树上进行点分治,需要找到重心保证自己的不会出现过于长的链来降低复杂度 #include <cstdio> #include & ...

  2. POJ 1741 Tree (树的点分治入门)

      Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 16172   Accepted: 5272 Descripti ...

  3. POJ 1741 树分治

    题目链接[http://poj.org/problem?id=1741] 题意: 给出一颗树,然后寻找点对(u,v)&&dis[u][v] < k的对数. 题解: 这是一个很经典 ...

  4. poj 1741 树的分治

    思路:这题我是看 漆子超<分治算法在树的路径问题中的应用>写的. 附代码: #include<iostream> #include<cstring> #includ ...

  5. POJ 1741 Tree 树上点分治

    题目链接:http://poj.org/problem?id=1741 题意: 给定一棵包含$n$个点的带边权树,求距离小于等于K的点对数量 题解: 显然,枚举所有点的子树可以获得答案,但是朴素发$O ...

  6. POJ 1741 Tree (点分治)

                                                                        Tree Time Limit: 1000MS   Memory ...

  7. poj 1741 Tree(点分治)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15548   Accepted: 5054 Description ...

  8. poj1741_Tree(树的点分治入门题)

    题目链接:poj1741_Tree 题意: 给你一颗n个节点的树,每条边有一个值,问有多少点对(u,v),满足u->v的最短路径小于k. 题解: 典型的树的分治,板子题. #include< ...

  9. POJ 1741 树上 点的 分治

    题意就是求树上距离小于等于K的点对有多少个 n2的算法肯定不行,因为1W个点 这就需要分治.可以看09年漆子超的论文 本题用到的是关于点的分治. 一个重要的问题是,为了防止退化,所以每次都要找到树的重 ...

随机推荐

  1. 【iOS】swift 74个Swift标准库函数

    本文译自 Swift Standard Library: Documented and undocumented built-in functions in the Swift standard li ...

  2. js判断flash文件是否加载完毕

    轮询判断加载进度 img的加载完成有onload方法,一直不知道该怎么判断swf文件是否加载完毕了? 在应用中使用了轮询判断加载进度值PercentLoaded是否达到100,经测试,可以达到效果. ...

  3. IDEA插件和快捷设置

    前言 IDEA全名Intellij IDEA,是Java开发的集成环境,它有两个版本,专业版(Ultimate)和社区版(Community),专业版需要注册,而社区版不用注册,同时需要注意的是社区版 ...

  4. 阿里云API网关(15)监控预警

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  5. GIT入门笔记(1)- Git的基本概念

    一.概念和定义 1.git是什么 许多人习惯用复制整个项目目录的方式来保存不同的项目版本,或许还会改名加上备份时间以示区别.这么做唯一的好处就是简单.不过坏处也不少:有时候会混淆所在的工作目录,一旦弄 ...

  6. virtualbox中linux系统与windows实现共享文件夹

    最近有一次,需要在linux获取在我windows系统里的安装包,但是呢不论如何也拿不过去. virtualbox虽然提供了双向拖放,但是实在是太不健壮了,感觉基本就没好使过. 于是我想到了用共享文件 ...

  7. web框架之Flask

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  8. 【笔记】css 自定义select 元素的箭头样式

    原文链接:https://www.imooc.com/qadetail/187585?t=281881 最近项目需要自定义select 元素的样式,搜索了一下发现了通过设置select 元素 css ...

  9. hdu1249 三角形分割平面---递推

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1249 题目大意: 用N个三角形最多可以把平面分成几个区域? 思路: 知道了直线和折线分割平面的情况这 ...

  10. spring boot 系列之三:spring boot 整合JdbcTemplate

    前面两篇文章我们讲了两件事情: 通过一个简单实例进行spring boot 入门 修改spring boot 默认的服务端口号和默认context path 这篇文章我们来看下怎么通过JdbcTemp ...