• BZOJ2610 [Poi2003]Monkeys


    首先我们离线,把操作倒过来,就变成每次把一棵树连到1所在的树上

    我们可以通过并查集来完成,然后就是每次并到1所在的树上时dfs一下这棵子树就好了

     1 /**************************************************************
     2     Problem: 2610
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:760 ms
     7     Memory:12528 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14 const int N = 2e5 + 5;
    15  
    16 struct edge {
    17     int next, to;
    18      
    19     edge() {}
    20     edge(int _n, int _t) : next(_n), to(_t) {}
    21 } e[N << 1];
    22  
    23 int n, m;
    24 int son[N][2], del[N][2];
    25 int q[N << 1][2], fa[N], ans[N];
    26 int first[N], tot;
    27  
    28 inline int read() {
    29     int x = 0, sgn = 1;
    30     char ch = getchar();
    31     while (ch < '0' || '9' < ch) {
    32         if (ch == '-') sgn = -1;
    33         ch = getchar();
    34     }
    35     while ('0' <= ch && ch <= '9') {
    36         x = x * 10 + ch - '0';
    37         ch = getchar();
    38     }
    39     return sgn * x;
    40 }
    41  
    42 inline void Add_Edges(int x, int y) {
    43     e[++tot] = edge(first[x], y), first[x] = tot;
    44     e[++tot] = edge(first[y], x), first[y] = tot;
    45 }
    46  
    47 #define y e[x].to
    48 void dfs(int p, int fa, int t) {
    49     ans[p] = t;
    50     int x;
    51     for (x = first[p]; x; x = e[x].next)
    52         if (y != fa) dfs(y, p, t); 
    53 }
    54 #undef y
    55  
    56 int find_fa(int x) {
    57     return x == fa[x] ? x : fa[x] = find_fa(fa[x]);
    58 }
    59  
    60 inline void set_union(int x, int y, int t) {
    61     if (find_fa(x) == find_fa(y)) return;
    62     if (fa[x] == find_fa(1)) dfs(y, 0, t);
    63     else if (fa[y] == find_fa(1)) dfs(x, 0, t);
    64     else Add_Edges(x, y);
    65     fa[fa[x]] = fa[y];
    66 }
    67  
    68 int main() {
    69     int i, j, x, y;
    70     n = read(), m = read() - 1;
    71     for (i = 1; i <= n; ++i)
    72         son[i][0] = read(), son[i][1] = read(), fa[i] = i;
    73     for (i = 0; i <= m; ++i) {
    74         x = read(), y = read() - 1;
    75         q[i][0] = x, q[i][1] = y, del[x][y] = 1;
    76     }
    77     for (i = 1; i <= n; ++i)
    78         for (j = 0; j < 2; ++j)
    79             if (!del[i][j] && son[i][j] > 0) set_union(i, son[i][j], -1);
    80     for (i = m; ~i; --i)
    81         set_union(q[i][0], son[q[i][0]][q[i][1]], i);
    82     puts("-1");
    83     for (i = 2; i <= n; ++i) printf("%d
    ", ans[i]);
    84     return 0;
    85 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    守护线程与普通线程
    Java中实现多线程的两种方式之间的区别
    Python os.dup() 方法
    Python os.closerange() 方法
    Python os.close() 方法
    Python os.chroot() 方法
    Python os.chmod() 方法
    JavaScript——基本包装类型
    javascript——function类型(this关键字)
    常用的正则
  • 原文地址:https://www.cnblogs.com/rausen/p/4324694.html
Copyright © 2020-2023  润新知