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
原文地址:https://www.cnblogs.com/rausen/p/4324694.html