POJ1741(树分治)
2015-10-29 23:28
381 查看
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <cmath> using namespace std; #define maxn 11111 #define maxm 21111 #define INF 11111111 #define size Size struct node { int from, to, next, w; }edge[maxm]; int n, k, cnt, ans, root; int head[maxn]; bool vis[maxn]; int size[maxn], num[maxn]; //以i为根的子树的节点 i的子树中最多的节点 int d[maxn], Min; void add_edge (int from, int to, int w) { edge[cnt].from = from, edge[cnt].to = to, edge[cnt].w = w, edge[cnt].next = head[from], head[from] = cnt++; } void dfs_size (int u, int fa) { size[u] = 1; num[u] = 0; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == fa || vis[v]) continue; dfs_size (v, u); size[u] += size[v]; if (size[v] > num[u]) { num[u] = size[v]; } } } void find_root (int u, int fa, int pre) { //找到重心 int cur = 0; cur = max (num[u], size[pre]-size[u]); if (cur < Min) { Min = cur; root = u; } for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (v == fa || vis[v]) continue; find_root (v, u, pre); } } int tmp[maxn], tot; void get_dis (int u, int fa, int dis) { //得到每个点到当前根的距离 tmp[tot++] = dis; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (vis[v] || v == fa) continue; d[v] = dis+edge[i].w; get_dis (v, u, d[v]); } } int solve (int u, int d) { int ans = 0; tot = 0; get_dis (u, 0, d); sort (tmp, tmp+tot); int r = tot-1, l = 0; while (r>l) { for (; tmp[r]+tmp[l] > k && r > l; r--) {} ans += r-l; l++; } return ans; } void dfs (int u) { Min = INF; dfs_size (u, 0); find_root (u, 0, u); vis[root] = 1; ans += solve (root, 0); for (int i = head[root]; i != -1; i = edge[i].next) { int v = edge[i].to; if (vis[v]) continue; ans -= solve (v, edge[i].w); dfs (v); } } int main () { //freopen ("in", "r", stdin); while (scanf ("%d%d", &n, &k) == 2 && n+k) { cnt = ans = 0; int u, v, w; memset (head, -1, sizeof head); for (int i = 1; i < n; i++) { scanf ("%d%d%d", &u, &v, &w); add_edge (u, v, w); add_edge (v, u, w); } memset (vis, 0, sizeof vis); dfs (1); printf ("%d\n", ans); } return 0; }
相关文章推荐
- 视图切换的动画api
- java.util.logging.Logger使用详解
- LeetCode Contains Duplicate II 数组
- 如何下载远程dll文件,并且执行不被360报毒
- 【C++】内联函数,inline
- 【HttpClient4.5中文教程】【第一章 :基础】1.3 HttpClient执行上下文
- FZU 2168
- android---(volley网络通信框架)
- 记录python数据持久存储的一点问题
- win7宿主机访问linux 虚拟机的tomcat、nginx
- 【HttpClient4.5中文教程】【第一章 :基础】1.2 HttpClient接口
- 算数-偶数和基数
- 【Android成长之路】全局大喇叭——广播机制的浅谈(使用本地广播)
- 在 Profiles 中添加特征值
- Spring3:AOP
- 每天一个Linux命令(7): cp
- Java多线程
- 通信协议制定
- iOS开发见闻-第4期
- 【HttpClient4.5中文教程】【第一章 :基础】1.1执行请求(三)