Little Zu Chongzhi's Triangles HDU
阿新 • • 發佈:2018-12-24
狀壓搜尋加剪枝。
#include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> #include <cmath> #include <vector> using namespace std; const int N = 10009; struct node{ int v, l; node() {}; node(int _v, int _l):v(_v),l(_l) {}; }; vector<node>Tree[N]; int n, k, size, s[N], f[N], root, deep[N], ans; vector<int>dep; bool used[N]; int x, y, z; void get_root(int now, int fa) { s[now] = 1; f[now] = 0; for (int i = 0; i < Tree[now].size(); i++) { int u = Tree[now][i].v; if (u != fa && !used[u]) { get_root(u, now); s[now] += s[u]; f[now] = max(f[now], s[u]); } } f[now] = max(f[now], size - s[now]); if (f[now] < f[root]) root = now; } void get_dep(int now, int fa) { dep.push_back(deep[now]); for (int i = 0; i < Tree[now].size(); i++) { int u = Tree[now][i].v; if (u != fa && ! used[u]) { deep[u] = deep[now] + Tree[now][i].l; get_dep(u, now); } } } int calc(int now, int init) { dep.clear(); deep[now] = init; get_dep(now, 0); sort(dep.begin(), dep.end()); int ret = 0; for (int l = 0, r = dep.size()-1; l < r;) { if (dep[l] + dep[r] <= k) ret += r-l++; else r--; } return ret; } void work(int now) { ans += calc(now, 0); used[now] =true; for (int i = 0; i < Tree[now].size(); i++) { int u = Tree[now][i].v; if (!used[u]) { ans -= calc(u, Tree[now][i].l); f[0] = size = s[u]; get_root(u, root = 0); work(root); } } } int main() { while (scanf("%d%d", &n, &k) != EOF) { if (n == 0 && k == 0) break; memset(used, 0, sizeof(used)); for (int i = 1; i <= n; i++) Tree[i].clear(); for (int i = 1; i < n; i++) { scanf("%d%d%d", &x, &y, &z); Tree[x].push_back(node(y, z)); Tree[y].push_back(node(x, z)); } f[0] = size = n; get_root(1, root = 0); ans = 0; work(root); printf("%d\n", ans); } return 0; }