zoukankan      html  css  js  c++  java
  • POJ 1741 tree

    树的分治学了好几天时间也不是很透彻,特别是09年OI论文还没看懂。。。。。

    这题很经典的一道树的分治

    可以参考09漆神OI论文

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <vector>
     4 #include <cstring>
     5 #include <iostream>
     6 using namespace std;
     7 #define N 10010
     8 struct node {
     9     int to, w;
    10     node() {};
    11     node(int _v, int _l): to(_v), w(_l) {};
    12 };
    13 vector<node> g[N];
    14 int n, k, sizee, s[N], f[N], root, d[N], K, ans;
    15 vector<int>dep;
    16 bool vis[N];
    17 void getroot(int now, int fa) {
    18     s[now] = 1; f[now] = 0;
    19     int u;
    20     for (int i=0; i<g[now].size(); i++)
    21         if ((u = g[now][i].to) != fa && !vis[u]) {
    22             getroot(u, now);
    23             s[now] += s[u];
    24             f[now] = max(f[now], s[u]);
    25         }
    26     f[now] = max(f[now], sizee-s[now]);
    27     if (f[now] < f[root]) root = now;
    28 }
    29 void getdep(int now, int fa) {
    30     dep.push_back(d[now]);
    31     int u;
    32     for (int i=0; i<g[now].size(); i++)
    33         if ((u = g[now][i].to) != fa && !vis[u]) {
    34             d[u] = d[now] + g[now][i].w;
    35             getdep(u, now);
    36         }
    37 }
    38 int calc(int now, int init) {
    39     dep.clear(); d[now] = init;
    40     getdep(now, 0);
    41     sort(dep.begin(), dep.end());
    42     int ret = 0;
    43     for (int l=0, r=dep.size()-1; l<r; )
    44         if (dep[l] + dep[r] <= K) ret += r-l++;
    45         else r--;
    46     return ret;
    47 }
    48 void work(int now) {
    49     int u;
    50     ans += calc(now, 0);
    51     vis[now] = true;
    52     for (int i=0; i<g[now].size(); i++)
    53         if (!vis[u = g[now][i].to]) {
    54             ans -= calc(u, g[now][i].w);
    55             f[0] = sizee = s[u];
    56             getroot(u, root=0);
    57             work(root);
    58         }
    59 }
    60 int main() {
    61     while (scanf("%d%d", &n, &K) == 2) {
    62         if (n == 0 && K == 0) break;
    63         for (int i=0; i<=n; i++) g[i].clear();
    64         memset(vis, false, sizeof(vis));
    65 
    66         int u, v, l;
    67         for (int i=1; i<n; i++) {
    68             scanf("%d%d%d", &u, &v, &l);
    69             g[u].push_back(node(v, l));
    70             g[v].push_back(node(u, l));
    71         }
    72         f[0] = sizee = n;
    73         getroot(1, root=0);
    74         ans = 0;
    75         work(root);
    76         printf("%d
    ", ans);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    权值线段树 学习笔记
    Codeforces Round #585 (Div. 2)
    a题解
    01Trie学习笔记
    学习笔记--线段树合并与分裂
    [NOIP10.6模拟赛]1.merchant题解--思维+二分
    [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
    [NOIP10.5模拟赛]1.a题解--离散化+异或线段树
    [NOIP10.5模拟赛]3.c题解--思维
    [NOIP10.3模拟赛]3.w题解--神奇树形DP
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5399156.html
Copyright © 2011-2022 走看看