zoukankan      html  css  js  c++  java
  • 长链剖分

    因为重链剖分叫重女儿所以长链剖分叫长女儿。 参考资料

    O(nlogn)-O(1)求k级祖先,O(logn)求lca(也就是二分答案之后求k级祖先判定...)。

    O(n)统计以深度为下标的信息。

    性质1,总链长是O(n)数量级的。

    写法跟树剖类似。


     应用1:求k级祖先。

    此处需要性质2:k级祖先所在长链,链长大于k。

    预处理出每个链头上下长度为链长的信息。

    值得注意的地方:len如果是最深深度,链长就是len - d。

    母亲的d比女儿要小......经常写反。

    模板题

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <vector>
      5 
      6 const int N = 300010;
      7 
      8 inline void read(int &x) {
      9     x = 0;
     10     char c = getchar();
     11     while(c < '0' || c > '9') c = getchar();
     12     while(c >= '0' && c <= '9') {
     13         x = (x << 3) + (x << 1) + c - 48;
     14         c = getchar();
     15     }
     16     return;
     17 }
     18 
     19 struct Edge {
     20     int nex, v;
     21 }edge[N << 1]; int tp;
     22 
     23 int e[N], n, father[N][20], son[N], len[N], d[N], top[N], pw[N];
     24 std::vector<int> fa[N], af[N];
     25 
     26 inline void add(int x, int y) {
     27     tp++;
     28     edge[tp].v = y;
     29     edge[tp].nex = e[x];
     30     e[x] = tp;
     31     return;
     32 }
     33 
     34 void DFS_1(int x, int f) { /// get d father son len
     35     father[x][0] = f;
     36     d[x] = d[f] + 1;
     37     len[x] = d[x];
     38     for(int i = e[x]; i; i = edge[i].nex) {
     39         int y = edge[i].v;
     40         if(y == f) {
     41             continue;
     42         }
     43         DFS_1(y, x);
     44         len[x] = std::max(len[x], len[y]);
     45         if(len[y] > len[son[x]]) {
     46             son[x] = y;
     47         }
     48     }
     49     return;
     50 }
     51 
     52 void DFS_2(int x, int f) { /// get top fa
     53     top[x] = f;
     54     if(son[x]) {
     55         DFS_2(son[x], f);
     56     }
     57     for(int i = e[x]; i; i = edge[i].nex) {
     58         int y = edge[i].v;
     59         if(y == father[x][0] || y == son[x]) continue;
     60         DFS_2(y, y);
     61     }
     62     return;
     63 }
     64 
     65 inline void prework() {
     66     for(int i = 2; i <= n; i++) pw[i] = pw[i >> 1] + 1;
     67     for(int j = 1; j <= pw[n]; j++) {
     68         for(int i = 1; i <= n; i++) {
     69             father[i][j] = father[father[i][j - 1]][j - 1];
     70         }
     71     }
     72     for(int x = 1; x <= n; x++) {
     73         if(top[x] != x) continue;
     74         int up = x, down = x;
     75         for(int i = 0; i <= len[x] - d[x]; i++) {
     76             fa[x].push_back(up);
     77             af[x].push_back(down);
     78             up = father[up][0];
     79             down = son[down];
     80         }
     81     }
     82     return;
     83 }
     84 
     85 inline int ask(int x, int k) {
     86     if(!k) return x;
     87     if(k >= d[x] || k < 0) return 0;
     88     int t = pw[k];
     89     x = father[x][t];
     90     if(!x) return 0;
     91     k -= (1 << t);
     92     int y = top[x];
     93     if(d[x] - d[y] >= k) {
     94         return af[y][d[x] - d[y] - k];
     95     }
     96     return fa[y][k - d[x] + d[y]];
     97 }
     98 
     99 int main() {
    100     int m;
    101     read(n);
    102     for(int i = 1, x, y; i < n; i++) {
    103         read(x); read(y);
    104         add(x, y); add(y, x);
    105     }
    106     DFS_1(1, 0);
    107     DFS_2(1, 1);
    108     prework();
    109     read(m);
    110     int lastans = 0;
    111     for(int i = 1, x, y; i <= m; i++) {
    112         read(x); read(y);
    113         lastans = ask(x ^ lastans, y ^ lastans);
    114         printf("%d
    ", lastans);
    115     }
    116     return 0;
    117 }
    AC代码

    例题:BZOJ4381 Odwiedziny

    对询问的步长根号分块。大于的暴力跳,小于的预处理出来,然后减去2 * lca即可。注意边界。(我居然1A了...写的check都没用到)

      1 #include <bits/stdc++.h>
      2 
      3 typedef long long LL;
      4 const int N = 50010;
      5 
      6 struct Edge {
      7     int nex, v;
      8 }edge[N << 1]; int tp;
      9 
     10 int e[N], n, T, father[N][20], pw[N], b[N], c[N], d[N], len[N], top[N], son[N];
     11 std::vector<int> fa[N], af[N];
     12 LL val[N], Val[N][300];
     13 
     14 inline void add(int x, int y) {
     15     tp++;
     16     edge[tp].v = y;
     17     edge[tp].nex = e[x];
     18     e[x] = tp;
     19     return;
     20 }
     21 
     22 void DFS_1(int x, int f) { /// get father d len son
     23     father[x][0] = f;
     24     d[x] = d[f] + 1;
     25     len[x] = d[x];
     26     for(int i = e[x]; i; i = edge[i].nex) {
     27         int y = edge[i].v;
     28         if(y == f) continue;
     29         DFS_1(y, x);
     30         len[x] = std::max(len[x], len[y]);
     31         if(len[y] > len[son[x]]) {
     32             son[x] = y;
     33         }
     34     }
     35     return;
     36 }
     37 
     38 void DFS_2(int x, int f) { /// get top
     39     top[x] = f;
     40     if(son[x]) DFS_2(son[x], f);
     41     for(int i = e[x]; i; i = edge[i].nex) {
     42         int y = edge[i].v;
     43         if(y == father[x][0] || y == son[x]) continue;
     44         DFS_2(y, y);
     45     }
     46     return;
     47 }
     48 
     49 inline int getKfa(int x, int k) {
     50     if(!k) return x;
     51     if(k < 0 || k >= d[x]) return 0;
     52     int t = pw[k];
     53     x = father[x][t];
     54     k -= (1 << t);
     55     int y = top[x];
     56     if(k <= d[x] - d[y]) {
     57         return af[y][d[x] - d[y] - k];
     58     }
     59     return fa[y][k - d[x] + d[y]];
     60 }
     61 
     62 void DFS_3(int x) {
     63     int y = father[x][0];
     64     for(int i = 1; i <= T; i++) {
     65         Val[x][i] = Val[y][i] + val[x];
     66         y = father[y][0];
     67     }
     68     for(int i = e[x]; i; i = edge[i].nex) {
     69         y = edge[i].v;
     70         if(y == father[x][0]) continue;
     71         DFS_3(y);
     72     }
     73     return;
     74 }
     75 
     76 inline void prework() {
     77     for(int i = 2; i <= n; i++) pw[i] = pw[i >> 1] + 1;
     78     for(int j = 1; j <= pw[n]; j++) {
     79         for(int i = 1; i <= n; i++) {
     80             father[i][j] = father[father[i][j - 1]][j - 1];
     81         }
     82     }
     83     for(int x = 1; x <= n; x++) {
     84         if(top[x] != x) continue;
     85         int up = x, down = x;
     86         for(int i = 0; i <= len[x] - d[x]; i++) {
     87             fa[x].push_back(up);
     88             af[x].push_back(down);
     89             up = father[up][0];
     90             down = son[down];
     91         }
     92     }
     93     DFS_3(1);
     94     return;
     95 }
     96 
     97 inline void check() {
     98     for(int x = 1; x <= n; x++) {
     99         printf("x = %d top = %d len = %d d = %d 
    father : ", x, top[x], len[x], d[x]);
    100         for(int i = 0; i <= pw[n]; i++) {
    101             printf("%d ", father[x][i]);
    102         }
    103         printf("
    Val : ");
    104         for(int i = 1; i <= T; i++) {
    105             printf("%d ", Val[x][i]);
    106         }
    107         printf("
    Kfa : ");
    108         for(int i = 0; i <= d[x]; i++) {
    109             printf("%d ", getKfa(x, i));
    110         }
    111         printf("
    
    ");
    112     }
    113     return;
    114 }
    115 
    116 inline int lca(int x, int y) {
    117     if(d[x] > d[y]) std::swap(x, y);
    118     int t = pw[n];
    119     while(t >= 0 && d[x] < d[y]) {
    120         if(d[father[y][t]] >= d[x]) {
    121             y = father[y][t];
    122         }
    123         t--;
    124     }
    125     if(x == y) return x;
    126     t = pw[n];
    127     while(t >= 0 && father[x][0] != father[y][0]) {
    128         if(father[x][t] != father[y][t]) {
    129             x = father[x][t];
    130             y = father[y][t];
    131         }
    132         t--;
    133     }
    134     return father[x][0];
    135 }
    136 
    137 int main() {
    138     scanf("%d", &n);
    139     T = sqrt(n);
    140     for(int i = 1; i <= n; i++) {
    141         scanf("%d", &val[i]);
    142     }
    143     for(int i = 1, x, y; i < n; i++) {
    144         scanf("%d%d", &x, &y);
    145         add(x, y); add(y, x);
    146     }
    147     DFS_1(1, 0);
    148     DFS_2(1, 1);
    149     prework();
    150 
    151     for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    152     for(int i = 1; i < n; i++) scanf("%d", &c[i]);
    153 
    154     for(int i = 1; i < n; i++) {
    155         int x = b[i], y = b[i + 1], z = lca(x, y);
    156         int step = (d[x] + d[y] - 2 * d[z]) % c[i];
    157         LL ans = 0;
    158         if(step) {
    159             ans += val[y];
    160             y = getKfa(y, step);
    161         }
    162         if(c[i] > T) { /// bf
    163             while(d[x] > d[z]) {
    164                 ans += val[x];
    165                 x = getKfa(x, c[i]);
    166             }
    167             while(d[y] > d[z]) {
    168                 ans += val[y];
    169                 y = getKfa(y, c[i]);
    170             }
    171             if(x == z) ans += val[z];
    172         }
    173         else {
    174             step = (d[x] - d[z]) % c[i];
    175             if(!step) ans -= val[z];
    176             int up = getKfa(x, ((d[x] - d[z]) / c[i] + 1) * c[i]);
    177             ans += (Val[x][c[i]] - Val[up][c[i]]);
    178             if(d[y] >= d[z]) {
    179                 up = getKfa(y, ((d[y] - d[z]) / c[i] + 1) * c[i]);
    180                 ans += (Val[y][c[i]] - Val[up][c[i]]);
    181             }
    182         }
    183         printf("%lld
    ", ans);
    184     }
    185 
    186     return 0;
    187 }
    AC代码

    应用2:统计信息。

    关于内存分配:开一个N的数组就行了。把一条链上每个点的起始位置分配成连续的即可。注意不要越界了。

    例题:CF1009F。注意合并的时候要更新答案。合并短女儿(?)链长的长度。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 2000010;
     4 
     5 struct Edge {
     6     int nex, v;
     7 }edge[N << 1]; int tp;
     8 
     9 int e[N], top[N], len[N], d[N], fa[N], son[N], n;
    10 int f[N], op[N], num, ans[N];
    11 
    12 inline void add(int x, int y) {
    13     tp++;
    14     edge[tp].v = y;
    15     edge[tp].nex = e[x];
    16     e[x] = tp;
    17     return;
    18 }
    19 
    20 void DFS_1(int x, int f) {
    21     fa[x] = f;
    22     d[x] = d[f] + 1;
    23     len[x] = d[x];
    24     for(int i = e[x]; i; i = edge[i].nex) {
    25         int y = edge[i].v;
    26         if(y == f) {
    27             continue;
    28         }
    29         DFS_1(y, x);
    30         len[x] = std::max(len[x], len[y]);
    31         if(len[y] > len[son[x]]) {
    32             son[x] = y;
    33         }
    34     }
    35     return;
    36 }
    37 
    38 void DFS_2(int x, int f) {
    39     top[x] = f;
    40     op[x] = ++num;
    41     if(son[x]) DFS_2(son[x], f);
    42     for(int i = e[x]; i; i = edge[i].nex) {
    43         int y = edge[i].v;
    44         if(y == fa[x] || y == son[x]) continue;
    45         DFS_2(y, y);
    46     }
    47     return;
    48 }
    49 
    50 void update(int x, int y) {
    51     if(f[op[x] + ans[x]] < f[op[x] + ans[y] + 1]) {
    52         ans[x] = ans[y] + 1;
    53     }
    54     else if(f[op[x] + ans[x]] == f[op[x] + ans[y] + 1]) {
    55         ans[x] = std::min(ans[x], ans[y] + 1);
    56     }
    57     return;
    58 }
    59 
    60 void DFS(int x) { /// DP
    61     f[op[x]]++;
    62     ans[x] = 0;
    63     if(son[x]) {
    64         DFS(son[x]);
    65         update(x, son[x]);
    66     }
    67     for(int i = e[x]; i; i = edge[i].nex) {
    68         int y = edge[i].v;
    69         if(y == fa[x] || y == son[x]) continue;
    70         DFS(y);
    71         for(int j = 0; j <= len[y] - d[y]; j++) {
    72             f[op[x] + j + 1] += f[op[y] + j];
    73             if(f[op[x] + j + 1] > f[op[x] + ans[x]]) {
    74                 ans[x] = j + 1;
    75             }
    76             else if(f[op[x] + j + 1] == f[op[x] + ans[x]]) {
    77                 ans[x] = std::min(ans[x], j + 1);
    78             }
    79         }
    80         update(x, y);
    81     }
    82     return;
    83 }
    84 
    85 int main() {
    86     scanf("%d", &n);
    87     for(int i = 1, x, y; i < n; i++) {
    88         scanf("%d%d", &x, &y);
    89         add(x, y); add(y, x);
    90     }
    91     DFS_1(1, 0);
    92     DFS_2(1, 1);
    93     DFS(1);
    94     for(int i = 1; i <= n; i++) printf("%d
    ", ans[i]);
    95     return 0;
    96 }
    AC代码

    还可以OSU on tree来做。

    BZOJ3252: 攻略

    正解是DFS序,不过有个长链剖分的蛇皮怪做法.....首先转化成k个不相交的竖链。

    本质都是贪心的取链删链。可以用DFS序维护每个点的收益,删链的时候暴力跳,每个点只会被跳到一次。

    长链剖分就直接选链长前k大即可......

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 200010;
     5 
     6 struct Edge {
     7     int nex, v;
     8 }edge[N << 1]; int tp;
     9 
    10 int top[N], son[N], fa[N], e[N];
    11 LL val[N], d[N], len[N];
    12 std::priority_queue<LL> Q;
    13 
    14 inline void add(int x, int y) {
    15     tp++;
    16     edge[tp].v = y;
    17     edge[tp].nex = e[x];
    18     e[x] = tp;
    19     return;
    20 }
    21 
    22 void DFS_1(int x, int f) {
    23     len[x] = d[x];
    24     fa[x] = f;
    25     for(int i = e[x]; i; i = edge[i].nex) {
    26         int y = edge[i].v;
    27         if(y == f) continue;
    28         d[y] = d[x] + val[y];
    29         DFS_1(y, x);
    30         len[x] = std::max(len[x], len[y]);
    31         if(len[y] > len[son[x]]) {
    32             son[x] = y;
    33         }
    34     }
    35     return;
    36 }
    37 
    38 void DFS_2(int x, int f) {
    39     top[x] = f;
    40     if(son[x]) DFS_2(son[x], f);
    41     for(int i = e[x]; i; i = edge[i].nex) {
    42         int y = edge[i].v;
    43         if(y == fa[x] || y == son[x]) continue;
    44         DFS_2(y, y);
    45     }
    46     return;
    47 }
    48 
    49 int main() {
    50     int n, k;
    51     scanf("%d%d", &n, &k);
    52     for(int i = 1; i <= n; i++) scanf("%lld", &val[i]);
    53     for(int i = 1, x, y; i < n; i++) {
    54         scanf("%d%d", &x, &y);
    55         add(x, y); add(y, x);
    56     }
    57 
    58     d[1] = val[1];
    59     DFS_1(1, 0);
    60     DFS_2(1, 1);
    61 
    62     for(int x = 1; x <= n; x++) {
    63         if(top[x] == x) Q.push(len[x] - d[fa[x]]);
    64     }
    65     LL ans = 0;
    66     for(int i = 1; i <= k; i++) {
    67         if(!Q.size()) break;
    68         ans += Q.top();
    69         Q.pop();
    70     }
    71 
    72     printf("%lld
    ", ans);
    73     return 0;
    74 }
    AC代码

    BZOJ3522: Hotel

    这是水水版,但是n2DP居然卡我空间...转移顺序很毒,要memcpy。

     1 #include <bits/stdc++.h>
     2 
     3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
     4 #define rep(i, a, b) for(int i = a; i <= b; i++)
     5 
     6 typedef long long LL;
     7 const int N = 5010;
     8 
     9 struct Edge {
    10     int nex, v;
    11 }edge[N << 1]; int tp;
    12 
    13 int e[N], d[N], len[N];
    14 int f[N][N], g[N][N], t1[N], t2[N];
    15 LL ans;
    16 
    17 inline void add(int x, int y) {
    18     tp++;
    19     edge[tp].v = y;
    20     edge[tp].nex = e[x];
    21     e[x] = tp;
    22     return;
    23 }
    24 
    25 void DFS(int x, int fa) {
    26     d[x] = d[fa] + 1;
    27     f[x][0] = 1;
    28     len[x] = d[x];
    29     forson(x, i) {
    30         int y = edge[i].v;
    31         if(y == fa) continue;
    32         DFS(y, x);
    33         len[x] = std::max(len[x], len[y]);
    34         /// DP ????
    35         memcpy(t1, f[x], sizeof(f[x]));
    36         memcpy(t2, g[x], sizeof(g[x]));
    37         for(int j = len[y] - d[y]; j >= 0; j--) {
    38             ans += t1[j] * g[y][j + 1];
    39             ans += t2[j + 1] * f[y][j];
    40             //printf("ans += %lld * %lld 
    ", t1[j], g[y][j + 1]);
    41             //printf("ans += %lld * %lld 
    ", t2[j + 1], f[y][j]);
    42             //printf("ans = %lld 
    ", ans);
    43             g[x][j + 1] += f[y][j] * t1[j + 1]; /// merge f -> g
    44             f[x][j + 1] += f[y][j]; /// f -> f
    45             g[x][j] += g[y][j + 1]; /// g -> g
    46         }
    47         /*printf("x = %d  y = %d 
    ", x, y);
    48         rep(j, 0, len[x]) {
    49             printf("%d  f %lld  g %lld 
    ", j, f[x][j], g[x][j]);
    50         }
    51         puts("");*/
    52     }
    53     return;
    54 }
    55 
    56 int main() {
    57     //freopen("in.in", "r", stdin);
    58     //freopen("my.out", "w", stdout);
    59 
    60     //printf("%d 
    ", sizeof(f) * 2 / 1048576);
    61     int n;
    62     scanf("%d", &n);
    63     rep(i, 1, n - 1) {
    64         int x, y;
    65         scanf("%d%d", &x, &y);
    66         add(x, y); add(y, x);
    67     }
    68     DFS(1, 0);
    69     printf("%lld
    ", ans);
    70     return 0;
    71 }
    50分DP

    有一种做法是枚举中间点。

    用指针实现的长链剖分。注意这个倒着的g数组空间不好精确开......多开点就完事了。

      1 #include <bits/stdc++.h>
      2  
      3 #define forson(x, i) for(int i = e[x]; i; i = edge[i].nex)
      4  
      5 typedef long long LL;
      6 const int N = 200010;
      7  
      8 struct Edge {
      9     int nex, v;
     10 }edge[N << 1]; int tp;
     11  
     12 int e[N], d[N], len[N], fa[N], numf, numg, son[N], top[N], lm[N];
     13 LL F[N << 1], G[N << 2], *f[N], *g[N];
     14 LL ans;
     15  
     16 inline void add(int x, int y) {
     17     tp++;
     18     edge[tp].v = y;
     19     edge[tp].nex = e[x];
     20     e[x] = tp;
     21     return;
     22 }
     23  
     24 /* the old DFS ELF ELF elf Asphodelus minori August yuzu-soft KID Key Leaf aquasoft kenoQ ASPHODELUS Restoration Hesitation Snow Moving Go On AlphaBeta Distrily Island
     25 void DFS(int x, int fa) {
     26     d[x] = d[fa] + 1;
     27     f[x][0] = 1;
     28     len[x] = d[x];
     29     forson(x, i) {
     30         int y = edge[i].v;
     31         if(y == fa) continue;
     32         DFS(y, x);
     33         len[x] = std::max(len[x], len[y]);
     34         /// DP ????
     35         memcpy(t1, f[x], sizeof(f[x]));
     36         memcpy(t2, g[x], sizeof(g[x]));
     37         for(int j = len[y] - d[y]; j >= 0; j--) {
     38             ans += t1[j] * g[y][j + 1];
     39             ans += t2[j + 1] * f[y][j];
     40             g[x][j + 1] += f[y][j] * t1[j + 1]; /// merge f -> g
     41             f[x][j + 1] += f[y][j]; /// f -> f
     42             g[x][j] += g[y][j + 1]; /// g -> g
     43         }
     44     }
     45     return;
     46 }
     47 */
     48  
     49 void DFS_1(int x, int father) {
     50     d[x] = d[father] + 1;
     51     fa[x] = father;
     52     len[x] = d[x];
     53     forson(x, i) {
     54         int y = edge[i].v;
     55         if(y == father) continue;
     56         DFS_1(y, x);
     57         len[x] = std::max(len[x], len[y]);
     58         if(len[y] > len[son[x]]) {
     59             son[x] = y;
     60         }
     61     }
     62     lm[x] = len[x] - d[x];
     63     return;
     64 }
     65  
     66 void DFS_2(int x, int father) {
     67     top[x] = father;
     68     f[x] = F + (++numf);
     69     g[x] = G + (++numg);
     70     //g[x] = G + numf;
     71     if(son[x]) {
     72         DFS_2(son[x], father);
     73     }
     74     forson(x, i) {
     75         int y = edge[i].v;
     76         if(y == fa[x] || y == son[x]) continue;
     77         numg += lm[y];
     78         DFS_2(y, y);
     79     }
     80  
     81     return;
     82 }
     83  
     84 inline void out(int x) {
     85     for(int i = 0; i <= len[x] - d[x]; i++) {
     86         printf("f %d %d = %d 
    ", x, i, f[x][i]);
     87     }
     88     for(int i = 0; i <= lm[x]; i++) {
     89         printf("g %d %d = %d 
    ", x, i, g[x][-i]);
     90     }
     91     return;
     92 }
     93  
     94 void DFS(int x) {
     95     f[x][0] = 1;
     96     if(son[x]) DFS(son[x]);
     97     ans += g[x][0];
     98  
     99     //printf("%d -- > %d 
    ", x, son[x]);
    100     //out(x);
    101  
    102     forson(x, i) {
    103         int y = edge[i].v;
    104         if(y == fa[x] || y == son[x]) continue;
    105         DFS(y);
    106         /// merge
    107         for(int i = 0; i <= len[x] - d[x] && i < lm[y]; i++) {
    108             ans += f[x][i] * g[y][-(i + 1)];
    109         }
    110         for(int i = 0; i <= len[y] - d[y] && i < lm[x]; i++) {
    111             ans += g[x][-(i + 1)] * f[y][i];
    112         }
    113         for(int i = 0; i <= len[y] - d[y] && i < lm[x] && i < len[x] - d[x]; i++) {
    114             g[x][-(i + 1)] += f[x][i + 1] * f[y][i]; /// i < d[x]
    115             //if(x == 5 && i + 1 == 2) printf("1111111111111111111");
    116         }
    117         for(int i = 0; i <= lm[x] && i < lm[y]; i++) {
    118             g[x][-(i)] += g[y][-(i + 1)]; /// i < d[x]
    119             //if(x == 5 && i == 2) printf("g %d %d = %lld 
    ", x, i, g[x][-i]);
    120             //if(x == 5 && i == 2) printf("222222222222222");
    121         }
    122         for(int i = 0; i <= len[y] - d[y] && i < len[x] - d[x]; i++) {
    123             f[x][i + 1] += f[y][i]; ///
    124         }
    125  
    126         //printf("%d -> %d 
    ", x, y);
    127         //out(x);
    128     }
    129     return;
    130 }
    131  
    132 int main() {
    133  
    134     int n;
    135     scanf("%d", &n);
    136     for(int i = 1; i < n; i++) {
    137         int x, y;
    138         scanf("%d%d", &x, &y);
    139         add(x, y); add(y, x);
    140     }
    141     DFS_1(1, 0);
    142     numg = N;
    143     DFS_2(1, 1);
    144     DFS(1);
    145     printf("%lld
    ", ans);
    146     return 0;
    147 }
    AC代码
  • 相关阅读:
    I Hate It
    hdu 2112 HDU Today ( Dijkstra )
    hdu 1280 前m大的数
    hdu 4252 A Famous City
    hdu 2647 Reward
    hdu 2845 Beans
    hdu 3548 Enumerate the Triangles ( 优 化 )
    hdu 3552 I can do it! (贪心)
    HDU 3033 I love sneakers!(分组背包变形)
    hdu 1712 ACboy needs your help 分组背包
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10486192.html
Copyright © 2011-2022 走看看