题干:

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

题目大意:

第一行给定n和k,然后给定一棵n个点的无向树,每条边有边权v,求点对(u,v)的个数,使得dis[u][v]<=k,n<=1e4

解题报告:

点分治裸题,注意求重心的时候别大于号小于号别弄反了,应该是求最大子树最小的顶点。还有别忘size的重构,很多代码貌似换根之后都没有重构,这样得到的all变量应该就是不对的,相应求出的当前子树的重心也应该是不对的。哦对了,别忘容斥。

AC代码:

//严格树的重心
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
int tot,head[MAX];
int n,k;
ll ans ;
struct Edge {int u,v,w,ne;
} e[MAX];
void add(int u,int v,int w) {e[++tot].u = u; e[tot].v = v; e[tot].w = w;e[tot].ne = head[u]; head[u] = tot;
}
int size[MAX],vis[MAX],son[MAX],rt,all;
void getRoot(int cur,int fa) {size[cur] = 1; son[cur] = 0;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(v == fa || vis[v]) continue;getRoot(v,cur);size[cur] += size[v];son[cur] = max(son[cur],size[v]);                }son[cur] = max(son[cur],all - size[cur]);if(son[rt] == 0 || son[rt] > son[cur]) rt = cur;
}
int tott,dis[MAX];
void getdis(int cur,int fa,int ddis) {dis[++tott] = ddis;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(v == fa || vis[v]) continue;getdis(v,cur,ddis + e[i].w);       }
}
int cal(int cur,int diss) {tott = 0; getdis(cur,0,diss);sort(dis+1,dis+tott+1);int l = 1, r = tott,res = 0;for(;l<r; l++) {while(dis[l]+dis[r] > k && r > l) r--;res += r-l;}return res;
}
void gx(int cur,int fa) {size[cur] = 1;for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(v == fa || vis[v]) continue;gx(v,cur);size[cur] += size[v];       }
}
void dfs(int cur) {rt = 0;getRoot(cur,0);cur = rt;//getRoot(cur,0);vis[cur] = 1;gx(cur,0);ans += cal(cur,0);for(int i = head[cur]; ~i; i = e[i].ne) {int v = e[i].v;if(vis[v]) continue;ans -= cal(v,e[i].w);all = size[v]; dfs(v);}
}
void init() {for(int i = 1; i<=n; i++) {vis[i] = size[i] = 0;head[i] = -1; }tot=ans=0;
}
int main()
{while(~scanf("%d%d",&n,&k) && n+k) {init();     for(int u,v,w,i = 1; i<=n-1; i++) {scanf("%d%d%d",&u,&v,&w);add(u,v,w);add(v,u,w);}    dfs(1);printf("%lld\n",ans);}     return 0 ;
}

【POJ - 1741】Tree(树分治,容斥,点分治,模板题)相关推荐

  1. POJ 1741 Tree 树分治

    题意: 给出一颗有\(n (n \leq 10^4)\)个节点的树,和一个\(k\).统计有多少个点对\(u, \, v(u \neq v)\)满足\(u\)到\(v\)的最短距离不超过\(k\). ...

  2. POJ 1741 Tree(树分治)

    去网上搜题解大多数都是说论文,搜了论文看了看,写的确实挺好,直接复制过来. 不过代码中有些细节还是要注意的,参考这篇http://blog.sina.com.cn/s/blog_6d5aa19a010 ...

  3. 2019.03.29 NOIP训练 友好国度(点分治+容斥)

    传送门 思路: 直接上点分治+容斥计算每个因数对应的贡献即可. 代码: #include<bits/stdc++.h> #define ri register int using name ...

  4. POJ 1741 Tree(点分治)

    题意 一棵 \(n\) 个节点的树,求两点间距离不超过 \(k\) 的点对对数. 思路 点分治模板题,点分治一般用来解决树上的路径问题,核心在于找出重心,算经过重心的合法路径,然后以重心把树劈成若干个 ...

  5. [POJ 1741] Tree

    Link: POJ 1741 传送门 Solution: 此题的难点在于点分治上的统计 如果依然采取每棵子树的结果与之前所有子树的结果合并的方式会比较麻烦 同时复杂度可能超过$O(n*log(n))$ ...

  6. P4336-[SHOI2016]黑暗前的幻想乡【矩阵树定理,容斥】

    正题 题目链接:https://www.luogu.com.cn/problem/P4336 题目大意 nnn个点,n−1n-1n−1个边集,求有多少种方案使得每个边集中恰好选出一条边使得这nnn个点 ...

  7. AT4352-[ARC101C] Ribbons on Tree【dp,容斥】

    正题 题目链接: https://www.luogu.com.cn/problem/AT4352 https://atcoder.jp/contests/arc101/tasks/arc101_c 题 ...

  8. ARC101E Ribbons on Tree 树形dp 容斥

    题目链接 题意: 给你一棵nnn个点的树,nnn是偶数,把这些点分成n2\frac{n}{2}2n​个点对,每个点对会把路径上的所有边覆盖,问你每条边至少覆盖一次有多少种配对方式.n<=5000 ...

  9. [矩阵树定理 容斥 meet in middle] Topcoder SRM 551 DIV1 Hard. SweetFruits

    枚举最后的树中有多少个是truly sweet的 答案就是 ∑i=0nfi×gi \sum_{i=0}^n f_i\times g_i 其中,fif_i 表示选出 ii 个水果使其价值和不超过Limi ...

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

    题目链接:http://poj.org/problem?id=1741 题意:给出一棵树,定义dis(u,v)为两个节点之间的距离.dis(u,v)<=K时成(u,v)是合法的.问有多少个合法的 ...

最新文章

  1. jQuery的ajax使用场景讨论(c#)
  2. Python成长之路第一篇(4)_if,for,while条件语句
  3. Docker容器中MySQL最大连接数被限制为214的解决方案
  4. Codeforces Round #504 E. Down or Right
  5. 如何通过CSS开启硬件加速来提高网站性能
  6. 物理层上/下行每个功能块需要的信息
  7. elementui组件_elementui 中 loading 组件源码解析(续)
  8. python创建时间序列_python时间序列按频率生成日期
  9. Sass与Compress实战:第一章
  10. fscapture下载收费吗?_如今听歌要收费,下载也要付费,你能接受国内音乐App这种改变吗...
  11. 【BST】Treap
  12. 解决state_enabled=false 不起作用的
  13. Codecademy学习Python
  14. Unity SRP初识之URP
  15. 常用编程工具:VS Code,这款编译工具到底好不好用?
  16. 【绘画素材】Q版线稿参考,欢迎临摹嗷
  17. 邮件服务器(eas)找不到服务器,Outlook2013无法配置qq邮箱exchange ActiveSync类型的解决方法...
  18. 利用python预测交通拥堵_Python pyecharts 绘制的交通拥堵情况地图
  19. wptx64能卸载吗_Win10如何卸载应用?Win10内置应用卸载方法
  20. 按住ctrl键多选_解决烦恼:按住Ctrl键单击选择时,阻止Windows意外复制文件

热门文章

  1. XML Schema ---complexType-----复合元素
  2. silverlight + wcf(json格式) + sqlserver存储过程分页
  3. [Leetcode][第112题][JAVA][路径总和][递归][队列]
  4. [Leedcode][JAVA][第983题][最低票价][动态规划]
  5. linux 识别文件类型,技术|Linux 中 7 个判断文件系统类型的方法
  6. mysql分库一致性_分库分表带来的完整性和一致性问题
  7. 压控元器件和流控元器件
  8. react textarea 空格为什么不换行_你需要的 React + TypeScript 50 条规范和经验
  9. java生成四则运算表达式_生成四则运算(java实现)
  10. pq分解法中b’怎么求_14.初中数学:二元一次方程组,加减消元法怎么解?视频有详细解题步骤...