Tree

Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 23380   Accepted: 7748

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

  1. 5 4
  2. 1 2 3
  3. 1 3 1
  4. 1 4 2
  5. 3 5 1
  6. 0 0

Sample Output

  1. 8

Source

 
  1. //2017-08-09
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <vector>
  7.  
  8. using namespace std;
  9.  
  10. const int N = ;
  11. int n, k, MAX, root, cnt, answer;
  12.  
  13. //链式前向星
  14. int head[N], tot;
  15. struct Edge{
  16. int next, to, w;
  17. }edge[N<<];
  18.  
  19. void add_edge(int u, int v, int w){
  20. edge[tot].w = w;
  21. edge[tot].to = v;
  22. edge[tot].next = head[u];
  23. head[u] = tot++;
  24. }
  25.  
  26. int size[N];//size[i]表示以i为根的子树的大小,包括i。
  27. int maxson[N];//maxson[i]表示以i为根的子树的最大儿子的大小。
  28. int dis[N];//dis[i]表示i到根的距离。
  29. bool vis[N];//vis[i]用来标记i点是否被删除。
  30.  
  31. void init(int n){
  32. answer = ;
  33. tot = ;
  34. memset(vis, , sizeof(vis));
  35. memset(head, -, sizeof(head));
  36. }
  37.  
  38. //计算出子树的大小
  39. void dfs_size(int u, int fa){
  40. size[u] = ;
  41. maxson[u] = ;
  42. for(int i = head[u]; ~i; i = edge[i].next){
  43. int v = edge[i].to;
  44. if(vis[v] || v == fa)continue;
  45. dfs_size(v, u);
  46. size[u] += size[v];
  47. if(size[v] > maxson[u])
  48. maxson[u] = size[v];
  49. }
  50. }
  51.  
  52. //找子树的重心。最大子树最小的点即为树的重心。
  53. void dfs_root(int r, int u, int fa){
  54. if(size[r] - size[u] > maxson[u])//size[r]-size[u]为u上面的树的尺寸
  55. maxson[u] = size[r] - size[u];
  56. if(maxson[u] < MAX){
  57. MAX = maxson[u];
  58. root = u;
  59. }
  60. for(int i = head[u]; ~i; i = edge[i].next){
  61. int v = edge[i].to;
  62. if(vis[v] || v == fa)continue;
  63. dfs_root(r, v, u);
  64. }
  65. }
  66.  
  67. //计算出子树中每个点距离重心的距离
  68. void dfs_dis(int u, int d, int fa){
  69. dis[cnt++] = d;
  70. for(int i = head[u]; ~i; i = edge[i].next){
  71. int v = edge[i].to;
  72. if(vis[v] || v == fa)continue;
  73. dfs_dis(v, d+edge[i].w, u);
  74. }
  75. }
  76.  
  77. //计算出以u为根的子树中距离和小于k的点对数
  78. int cal(int u, int d){
  79. int ans = ;
  80. cnt = ;
  81. dfs_dis(u, d, );
  82. sort(dis, dis+cnt);
  83. for(int i = , j = cnt-; i < j; i++){
  84. while(dis[i]+dis[j] > k && i < j)//双指针
  85. j--;
  86. ans += j-i;
  87. }
  88. return ans;
  89. }
  90.  
  91. //分治,找到树的重心,分为经过重心的点对和不经过重心的点对。
  92. void solve(int u){
  93. MAX = n;
  94. dfs_size(u, );
  95. dfs_root(u, u, );
  96. answer += cal(root, );
  97. vis[root] = ;
  98. for(int i = head[root]; ~i; i = edge[i].next){
  99. int v = edge[i].to;
  100. if(vis[v])continue;
  101. answer -= cal(v, edge[i].w);
  102. solve(v);
  103. }
  104. }
  105.  
  106. int main()
  107. {
  108. //freopen("dataIn.txt", "r", stdin);
  109. while(scanf("%d%d", &n, &k)!=EOF){
  110. if(!n && !k)break;
  111. int u, v, w;
  112. init(n);
  113. for(int i = ; i < n-; i++){
  114. scanf("%d%d%d", &u, &v, &w);
  115. add_edge(u, v, w);
  116. add_edge(v, u, w);
  117. }
  118. solve();
  119. printf("%d\n", answer);
  120. }
  121.  
  122. return ;
  123. }

POJ1741(SummerTrainingDay08-G 树的点分治)的更多相关文章

  1. 【poj1741】Tree 树的点分治

    题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...

  2. POJ1741 Tree(树的点分治)

    题目给一棵边带权的树,统计路径长度<=k的点对数. 楼教主男人八题之一,分治算法在树上的应用. 一开始看论文看不懂,以为重心和距离那些是一遍预处理得来的..感觉上不敢想每棵子树都求一遍重心和距离 ...

  3. POJ1741 Tree(树的点分治基础题)

    Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v) ...

  4. POJ1741 Tree(树分治——点分治)题解

    题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...

  5. 牛客多校第三场 G Removing Stones(分治+线段树)

    牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...

  6. POJ1741——Tree(树的点分治)

    1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...

  7. hdu_5314_Happy King(树的点分治)

    题目链接:hdu_5314_Happy King 题意: 给出一颗n个结点的树,点上有权值: 求点对(x,y)满足x!=y且x到y的路径上最大值与最小值的差<=D: 题解: 还是树的点分治,在统 ...

  8. 【CF576E】Painting Edges 线段树按时间分治+并查集

    [CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...

  9. 【bzoj3697】采药人的路径 树的点分治

    题目描述 给出一棵 $n$ 个点的树,每条边的边权为1或0.求有多少点对 $(i,j)$ ,使得:$i$ 到 $j$ 的简单路径上存在点 $k$ (异于 $i$ 和 $j$ ),使得 $i$ 到 $k ...

  10. 【bzoj3362/3363/3364/3365】[Usaco2004 Feb]树上问题杂烩 并查集/树的直径/LCA/树的点分治

    题目描述 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样, 图中农场用F ...

随机推荐

  1. postgresql-日志表

    pg_log,数据库日志表postgresqllog CREATE TABLE postgres_log ( log_time timestamp(3) with time zone, 日志生成时间 ...

  2. 使用Express构建RESTful API

    RESTful服务 REST(Representational State Transfer)的意思是表征状态转移,它是一种基于HTTP协议的网络应用接口风格,充分利用HTTP的方法实现统一风格接口的 ...

  3. [POC]K8 DLLhijack Test

    POC: 2016.11 Winrar却持 XP资源管理器却持 DLL却持VS全版本 https://www.cnblogs.com/k8gege/p/10261254.html POC:https: ...

  4. Centos 7 安装 Redis 3.2

    环境: Centos 7 GCC            #未安装,使用yum install gcc安装 1.下载redis 官方下载网站:https://redis.io/download.请在页面 ...

  5. 02-04:springboot 访问静态资源

    1.SpringBoot从classpath/static的目录下:(目录名称必须叫static,可以理解为根目录为static) 2.servletContext根目录下,进行查找: 在src/ma ...

  6. eclipse maven jdk全局设置

    <profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</acti ...

  7. Yum软件包管理详解

    目录 1. Yum 1.1 检查和更新包 1.1.1 查询更新 1.1.2 更新包 1.1.3 使用 ISO 和 Yum 离线升级系统 1.2 使用包 1.2.1 搜索包 1.2.2 列出包 1.2. ...

  8. Chapter 3 Phenomenon——20

    "All I know is that you weren't anywhere near me — 所有我知道的就是你当时不在我旁边的任何地方—— Tyler didn't see you ...

  9. zmq 自动绑定socket

    def auto_bind(socket): """ auto bind zmq socket :param socket: socket instance :retur ...

  10. Maven 入门——认识 Maven

    Maven /ˈmāvən/ ,可以翻译成"专家",是一款来自 Apache 组织的开源项目,用于项目管理.主要服务于基于 Java 平台的项目构建.依赖管理和项目信息管理. 构建 ...