POJ1987(树分治)
来源:互联网 发布:数据库安全防护总结 编辑:程序博客网 时间:2024/06/03 14:42
k的值很大答案应该用long long。
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>using namespace std;#define maxn 111111#define maxm 211111#define INF 11111111#define size Sizestruct node { int from, to, next; long long w;}edge[maxm];int n, m, k, cnt, root;long long ans;int head[maxn];bool vis[maxn];int size[maxn], num[maxn]; //以i为根的子树的节点 i的子树中最多的节点long long 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) { //找到重心 long long 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) { long long 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, &m) == 2) { cnt = ans = 0; int u, v, w; char op[10]; memset (head, -1, sizeof head); for (int i = 1; i < n; i++) { scanf ("%d%d%d%s", &u, &v, &w, &op); add_edge (u, v, w); add_edge (v, u, w); } scanf ("%d", &k); memset (vis, 0, sizeof vis); dfs (1); printf ("%lld\n", ans); } return 0;}
0 0
- POJ1987(树分治)
- poj1987 树的点分治
- poj1987 Distance Statistics 树的分治
- #POJ1987#Distance Statistics(树+点分治)
- POJ1987 Distance Statistics——树的分治
- 【POJ1987】Distance Statistics ==【POJ1741】 树分治
- [树的点分治] [POJ1741/POJ1987] Tree/Distance Statistics
- POJ1987 Distance Statistics【点分治】
- [POJ1987]Distance Statistics(点分治)
- 树分治-点分治
- 【poj1987】Distance Statistics
- POJ1987-Distance Statistics
- 树分治(点分治+边分治)
- 树分治
- 树分治
- 树分治
- 树的分治-点分治
- POJ1987——Distance Statistics
- Android Radio Interface Layer
- nginx 正则表达式匹配入门篇 .
- 实例分析JVM安全体系:双亲委派、命名空间、保护域、策略
- HDU-1029-Ignatius and the Princess IV
- 添加core 服务和app 服务 root 权限执行
- POJ1987(树分治)
- update-alternatives
- PHP知识点小记
- 64位Win7 IIS报 CS0016错误 解决办法
- House Robber II
- VTK+cmake+vs2008安装和编译,学习笔记
- spring mvc 接收返回json串
- Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
- Linux 文件和目录的属性