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.

题目大意:给一个带边权的树,问有多少对点满足dist(i,j)<=k

思路:可以参考2009年的国家集训队论文《分治算法在树的路径问题中的应用》——漆子超。

代码(188MS):

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstring>
  5. using namespace std;
  6.  
  7. const int MAXN = ;
  8. const int MAXE = ;
  9. const int INF = 0x7fff7fff;
  10.  
  11. int head[MAXN], size[MAXN], maxSize[MAXN];
  12. int list[MAXN], cnt;
  13. bool del[MAXN];
  14. int to[MAXE], next[MAXE], cost[MAXE];
  15. int n, k, ecnt;
  16.  
  17. void init() {
  18. memset(head, -, sizeof(head));
  19. memset(del, , sizeof(del));
  20. ecnt = ;
  21. }
  22.  
  23. void add_edge(int u, int v, int c) {
  24. to[ecnt] = v; cost[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
  25. to[ecnt] = u; cost[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++;
  26. }
  27.  
  28. void dfs1(int u, int f) {
  29. size[u] = ;
  30. maxSize[u] = ;
  31. for(int p = head[u]; ~p; p = next[p]) {
  32. int &v = to[p];
  33. if(v == f || del[v]) continue;
  34. dfs1(v, u);
  35. size[u] += size[v];
  36. maxSize[u] = max(maxSize[u], size[v]);
  37. }
  38. list[cnt++] = u;
  39. }
  40.  
  41. int get_root(int u, int f) {
  42. cnt = ;
  43. dfs1(u, f);
  44. int ret, maxr = INF;
  45. for(int i = ; i < cnt; ++i) {
  46. int &x = list[i];
  47. if(max(maxSize[x], size[u] - size[x]) < maxr) {
  48. ret = x;
  49. maxr = max(maxSize[x], size[u] - size[x]);
  50. }
  51. }
  52. return ret;
  53. }
  54.  
  55. void dfs2(int u, int f, int dis) {
  56. list[cnt++] = dis;
  57. for(int p = head[u]; ~p; p = next[p]) {
  58. int &v = to[p];
  59. if(v == f || del[v]) continue;
  60. dfs2(v, u, dis + cost[p]);
  61. }
  62. }
  63.  
  64. int calc(int a, int b) {
  65. int j = b - , ret = ;
  66. for(int i = a; i < b; ++i) {
  67. while(list[i] + list[j] > k && i < j) --j;
  68. ret += j - i;
  69. if(j == i) break;
  70. }
  71. return ret;
  72. }
  73.  
  74. int ans = ;
  75.  
  76. void work(int u, int f) {
  77. int root = get_root(u, f);
  78. del[root] = true;
  79. int last = ; cnt = ;
  80. for(int p = head[root]; ~p; p = next[p]) {
  81. int &v = to[p];
  82. if(del[v]) continue;
  83. dfs2(v, root, cost[p]);
  84. sort(list + last, list + cnt);
  85. ans -= calc(last, cnt);
  86. last = cnt;
  87. }
  88. list[cnt++] = ;
  89. sort(list, list + cnt);
  90. ans += calc(, cnt);
  91. for(int p = head[root]; ~p; p = next[p]) {
  92. int &v = to[p];
  93. if(del[v]) continue;
  94. work(v, root);
  95. }
  96. }
  97.  
  98. int main() {
  99. while(scanf("%d%d", &n, &k) != EOF) {
  100. if(n == && k == ) break;
  101. init();
  102. for(int i = ; i < n; ++i) {
  103. int u, v, c;
  104. scanf("%d%d%d", &u, &v, &c);
  105. add_edge(u, v, c);
  106. }
  107. ans = ;
  108. work(, );
  109. printf("%d\n", ans);
  110. }
  111. }

POJ 1741 Tree(树的分治)的更多相关文章

  1. POJ 1741 Tree 树的分治

    原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...

  2. poj 1741 Tree (树的分治)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 30928   Accepted: 10351 Descriptio ...

  3. POJ 1741 Tree 树的分治(点分治)

    题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...

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

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

  5. POJ 1741 Tree(树的点分治,入门题)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description ...

  6. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  7. POJ 1741 Tree 树上点分治

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

  8. POJ 1741 Tree (点分治)

                                                                        Tree Time Limit: 1000MS   Memory ...

  9. poj 1741 Tree(点分治)

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

  10. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

随机推荐

  1. c++基础STL

    今天给大家介绍几个容器,包含的头文件为<vector>,<stack>,<queue>,<map>,<list>,<deque> ...

  2. 理解Redux以及如何在项目中的使用

    今天我们来聊聊Redux,这篇文章是一个进阶的文章,建议大家先对redux的基础有一定的了解,在这里给大家推荐一下阮一峰老师的文章: http://www.ruanyifeng.com/blog/20 ...

  3. CASE WHEN 批量更新

    单个值: UPDATE categories SET display_order = CASE id WHEN 1 THEN 3 WHEN 2 THEN 4 WHEN 3 THEN 5 END WHE ...

  4. PHPExcel 导入Excel数据 (导出下一篇我们继续讲解)

    一:使用composer下载 phpoffice/phpexcel 或者直接下载安装包 composer require phpoffice/phpexcel 二 1:导入数据 原理:读取文件,获取文 ...

  5. 网站用户行为分析——HBase的安装与配置

    Hbase介绍 HBase是一个分布式的.面向列的开源数据库,源于Google的一篇论文<BigTable:一个结构化数据的分布式存储系统>.HBase以表的形式存储数据,表有行和列组成, ...

  6. HashMap底层实现原理及扩容机制

    HashMap的数据结构:数组+链表+红黑树:Java7中的HashMap只由数组+链表构成:Java8引入了红黑树,提高了HashMap的性能:借鉴一张图来说明,原文:https://www.jia ...

  7. 【blockly教程】第六章 Blockly的进阶

    6.1 模块化程序设计  一个较大的程序一般应分为若干个程序模块,每一个模块用来实现一个特定的功能.所有的高级语言中都有子程序这个概念,用子程序实现模块的功能.比如在C语言中,子程序的作用是由函数完成 ...

  8. linux redhat NFS网络共享搭建

    nfs网络共享 测试环境: 服务端:redhat6.7 ip:192.168.1.100 客户端:redhat6.7 ip:192.168.1.110 一.服务端 1.创建共享文件夹 权限666即可 ...

  9. SQL Server 中对 FOR XML和FROM的转换处理

    在SQL Server中对XML的再操作转换: 方法1: --生成XML SELECT * FROM [T_BAS_预算科目] FOR XML PATH --把XML转成SQL表 declare @X ...

  10. git配置config记住密码

    设置记住密码(默认15分钟): git config --global credential.helper cache如果想自己设置时间,可以这样做: git config credential.he ...