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. scrapy crawl rules设置

    rules = [ Rule(SgmlLinkExtractor(allow=('/u012150179/article/details'), restrict_xpaths=('//li[@clas ...

  2. org.hibernate.hibernate.connection.release_mode

    org.hibernate.connection包的主要封装了通过JDBC来连接数据库的操作,用户可以以数据源的方式,或者通过特定数据库驱动的方式,甚至是自己定义连接类的方式来完成数据库的连接操作,包 ...

  3. Raid 5数据恢复原理以及raid 5数据恢复实际操作案例

    Raid 5数据恢复算法原理 要理解 raid 5数据恢复原理首先要先认识raid5,"分布式奇偶校验的独立磁盘结构"也就是我们称之为的raid 5数据恢复有一个概念需要理解,也就 ...

  4. Winserver+Apache+django部署

    废话不多说,干活直接上. winserver2012 + django2.0.1 + apache 部署过程 python ==> 3.4 64位 https://www.python.org/ ...

  5. python之路--day15---软件开发目录规范

    软件开发目录规范 bin--启动文件 conf--配置文件 core--核心代码 db--数据文件 lib--常用功能代码 log--日志文件 readme--软件介绍

  6. JQ 标签相关知识

    1.判断 checkbox 和 radio 是否选中 if($("标签选择器").is(":checked")) 2.改变 checkbox 选中状态 .pro ...

  7. Python内置函数(45)——ascii

    英文文档: ascii(object) As repr(), return a string containing a printable representation of an object, b ...

  8. Hadoop学习笔记一(HDFS架构)

    介绍 Hadoop分布式文件系统(HDFS)设计的运行环境是商用的硬件系统.他和现存的其他分布式文件系统存在很多相似点.不过HDFS和其他分布式文件系统的区别才是他的最大亮点,HDFS具有高容错的特性 ...

  9. axure 预览"HTTP/1.1 302 Found"

    使用Axure编辑原型时,点击预览出现"HTTP/1.1 302 Found" 第一想到的就是重新安装Axure和检查原型文件是否损坏,验证后证明前Axure和.rp文件都是完好的 ...

  10. python3下搜狗AI API实现

    1.背景 a.搜狗也发布了自己的人工智能 api,包括身份证ocr.名片ocr.文本翻译等API,初试感觉准确率一般般. b.基于python3. c.也有自己的签名生成这块,有了鹅厂的底子,相对写起 ...