/
2995.test.cpp
64 lines (58 loc) · 1.33 KB
/
2995.test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2995"
#include "my_template.hpp"
#include "other/io.hpp"
#include "graph/dsu_on_tree.hpp"
#include "ds/unionfind/unionfind.hpp"
void solve() {
LL(N, K);
Graph G(N);
G.read_tree();
Tree T(G);
VEC(pi, CD, N);
for (auto&& [c, d]: CD) --c, --d;
/*
頂点になっている:+x
連結成分ごとに、ロスの min を持たせる
*/
vc<int> tree(K, 1);
vc<int> history;
ll ans = 0;
vc<int> ANS(N);
UnionFind uf(K);
auto eval
= [&](int v) -> int { return (tree[v] ? uf.size(v) - 1 : uf.size(v)); };
auto ADD = [&](int v) -> void {
auto [c, d] = CD[v];
history.eb(c), history.eb(d);
c = uf[c], d = uf[d];
if (c == d) {
if (tree[c]) tree[c] = 0, ans++;
return;
}
ans -= eval(c) + eval(d);
uf.merge(c, d);
int r = uf[c];
tree[r] = tree[c] && tree[d];
ans += eval(r);
};
auto QUERY = [&](int v) -> void { ANS[v] = ans; };
auto RESET = [&]() -> void {
for (auto&& v: history) {
uf.dat[v] = -1;
tree[v] = 1;
}
ans = 0;
history.clear();
};
DSU_on_Tree(T, ADD, QUERY, RESET);
for (auto&& x: ANS) print(x);
}
signed main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
cout << setprecision(15);
ll T = 1;
// LL(T);
FOR(T) solve();
return 0;
}