#include <bits/stdc++.h>
using namespace std;
struct ComponentUnionFind {
bool is_chains = true;
vector<int> par;
vector<int> _degree;
int extra_edges = 0;
ComponentUnionFind(int n) : par(n, -1), _degree(n, 0) {}
int find(int i) {
return par[i] < 0 ? i : (par[i] = find(par[i]));
}
int csize(int i) {
return -par[find(i)];
}
int degree(int i) {
return _degree[i];
}
bool join(int i, int j) {
++_degree[i]; ++_degree[j];
if (_degree[i] > 2 || _degree[j] > 2) is_chains = false;
int ir = find(i), jr = find(j);
if (ir == jr) {
++extra_edges;
is_chains = false;
return false;
}
if (par[ir] > par[jr]) {
swap(i, j); swap(ir, jr);
}
par[ir] += par[jr]; par[jr] = ir;
return true;
}
};
ComponentUnionFind create_from_ban(const vector<pair<int, int>> &edge_list, int n, int banned) {
ComponentUnionFind cuf(n);
for (auto [u, v] : edge_list) {
if (u != banned && v != banned) cuf.join(u, v);
}
return cuf;
}
struct ParachuteRings {
int n;
vector<pair<ComponentUnionFind, int>> cufs;
vector<pair<int, int>> edge_list;
// size of the first cycle formed
optional<int> critical_cycle_size;
bool spoiled;
ParachuteRings(int n) : n(n), cufs{{ComponentUnionFind(n), -1}}, spoiled(false) {}
ParachuteRings() {}
int count_critical() {
if (spoiled) return 0;
// here, we know the graph is NOT spoiled
else if (cufs.size() > 1) {
int ans = 0;
for (auto &[cuf, _] : cufs) if (cuf.is_chains) ++ans;
return ans;
} else {
// if we have no critical cycle, everything must still be chains
return critical_cycle_size.value_or(n);
}
}
void reset_cufs(int i) {
vector<pair<ComponentUnionFind, int>> new_cufs;
vector<int> bans;
for (auto [u, v] : edge_list) {
if (u == i) bans.push_back(v);
if (v == i) bans.push_back(u);
}
bans.push_back(i);
for (int v : bans) new_cufs.emplace_back(create_from_ban(edge_list, n, v), v);
cufs = new_cufs;
}
void link(int i, int j) {
edge_list.emplace_back(i, j);
if (spoiled) return;
if (cufs.size() > 1) {
for (auto &[cuf, banned] : cufs) {
if (!(i == banned || j == banned)) cuf.join(i, j);
}
} else {
auto &cuf = cufs[0].first;
bool cycle_created = !cuf.join(i, j);
if (cuf.degree(i) > 2 || cuf.degree(j) > 2) {
if (cuf.degree(i) > 2) reset_cufs(i);
else reset_cufs(j);
} else {
// all nodes still have degree <= 2
// now, we must check for cycles
// here, i guarantee cuf is still valid
if (cycle_created) {
if (cuf.extra_edges >= 2) {
// we have two disjoint cycles, spoil the graph now
spoiled = true;
} else {
critical_cycle_size = cuf.csize(i);
}
}
}
// if i fuck up here because i access cuf when i invalidated it that is
// unironically a "muh memory safety!!!!!" moment
}
}
void dump_state() {
return;
cerr << "!!! STATE DUMP " << endl;
if (spoiled) cerr << "spoiled" << endl;
else {
cerr << "crit cycle " << critical_cycle_size.value_or(-1) << endl;
cerr << cufs.size() << "simulations" << endl;
for (auto &[cuf, banned] : cufs) {
cerr << "cuf with ban" << banned << " = " << cuf.is_chains << endl;
}
}
}
};
ParachuteRings pr;
void Init(int N) {
pr = ParachuteRings(N);
pr.dump_state();
}
void Link(int A, int B) {
pr.link(A, B);
pr.dump_state();
}
int CountCritical() {
return pr.count_critical();
pr.dump_state();
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
604 KB |
Output is correct |
3 |
Correct |
1 ms |
860 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
604 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
1 ms |
604 KB |
Output is correct |
9 |
Correct |
1 ms |
860 KB |
Output is correct |
10 |
Correct |
1 ms |
860 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
100 ms |
17284 KB |
Output is correct |
2 |
Correct |
233 ms |
62580 KB |
Output is correct |
3 |
Correct |
292 ms |
75812 KB |
Output is correct |
4 |
Correct |
185 ms |
33460 KB |
Output is correct |
5 |
Correct |
199 ms |
33508 KB |
Output is correct |
6 |
Correct |
192 ms |
32892 KB |
Output is correct |
7 |
Correct |
299 ms |
75300 KB |
Output is correct |
8 |
Correct |
240 ms |
80744 KB |
Output is correct |
9 |
Correct |
285 ms |
90124 KB |
Output is correct |
10 |
Correct |
195 ms |
32952 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
604 KB |
Output is correct |
3 |
Correct |
1 ms |
860 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
604 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
1 ms |
604 KB |
Output is correct |
9 |
Correct |
1 ms |
860 KB |
Output is correct |
10 |
Correct |
1 ms |
860 KB |
Output is correct |
11 |
Correct |
1 ms |
856 KB |
Output is correct |
12 |
Correct |
3 ms |
1372 KB |
Output is correct |
13 |
Correct |
3 ms |
1372 KB |
Output is correct |
14 |
Correct |
3 ms |
1116 KB |
Output is correct |
15 |
Correct |
2 ms |
1884 KB |
Output is correct |
16 |
Correct |
2 ms |
860 KB |
Output is correct |
17 |
Correct |
2 ms |
1120 KB |
Output is correct |
18 |
Correct |
3 ms |
1884 KB |
Output is correct |
19 |
Correct |
2 ms |
860 KB |
Output is correct |
20 |
Correct |
2 ms |
1372 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
604 KB |
Output is correct |
3 |
Correct |
1 ms |
860 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
604 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
1 ms |
604 KB |
Output is correct |
9 |
Correct |
1 ms |
860 KB |
Output is correct |
10 |
Correct |
1 ms |
860 KB |
Output is correct |
11 |
Correct |
1 ms |
856 KB |
Output is correct |
12 |
Correct |
3 ms |
1372 KB |
Output is correct |
13 |
Correct |
3 ms |
1372 KB |
Output is correct |
14 |
Correct |
3 ms |
1116 KB |
Output is correct |
15 |
Correct |
2 ms |
1884 KB |
Output is correct |
16 |
Correct |
2 ms |
860 KB |
Output is correct |
17 |
Correct |
2 ms |
1120 KB |
Output is correct |
18 |
Correct |
3 ms |
1884 KB |
Output is correct |
19 |
Correct |
2 ms |
860 KB |
Output is correct |
20 |
Correct |
2 ms |
1372 KB |
Output is correct |
21 |
Correct |
7 ms |
1816 KB |
Output is correct |
22 |
Correct |
12 ms |
2532 KB |
Output is correct |
23 |
Correct |
18 ms |
3228 KB |
Output is correct |
24 |
Correct |
18 ms |
7080 KB |
Output is correct |
25 |
Correct |
8 ms |
7504 KB |
Output is correct |
26 |
Correct |
18 ms |
7308 KB |
Output is correct |
27 |
Correct |
16 ms |
3788 KB |
Output is correct |
28 |
Correct |
21 ms |
7016 KB |
Output is correct |
29 |
Correct |
16 ms |
7500 KB |
Output is correct |
30 |
Correct |
20 ms |
3724 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
348 KB |
Output is correct |
2 |
Correct |
1 ms |
604 KB |
Output is correct |
3 |
Correct |
1 ms |
860 KB |
Output is correct |
4 |
Correct |
0 ms |
348 KB |
Output is correct |
5 |
Correct |
1 ms |
348 KB |
Output is correct |
6 |
Correct |
1 ms |
604 KB |
Output is correct |
7 |
Correct |
1 ms |
604 KB |
Output is correct |
8 |
Correct |
1 ms |
604 KB |
Output is correct |
9 |
Correct |
1 ms |
860 KB |
Output is correct |
10 |
Correct |
1 ms |
860 KB |
Output is correct |
11 |
Correct |
100 ms |
17284 KB |
Output is correct |
12 |
Correct |
233 ms |
62580 KB |
Output is correct |
13 |
Correct |
292 ms |
75812 KB |
Output is correct |
14 |
Correct |
185 ms |
33460 KB |
Output is correct |
15 |
Correct |
199 ms |
33508 KB |
Output is correct |
16 |
Correct |
192 ms |
32892 KB |
Output is correct |
17 |
Correct |
299 ms |
75300 KB |
Output is correct |
18 |
Correct |
240 ms |
80744 KB |
Output is correct |
19 |
Correct |
285 ms |
90124 KB |
Output is correct |
20 |
Correct |
195 ms |
32952 KB |
Output is correct |
21 |
Correct |
1 ms |
856 KB |
Output is correct |
22 |
Correct |
3 ms |
1372 KB |
Output is correct |
23 |
Correct |
3 ms |
1372 KB |
Output is correct |
24 |
Correct |
3 ms |
1116 KB |
Output is correct |
25 |
Correct |
2 ms |
1884 KB |
Output is correct |
26 |
Correct |
2 ms |
860 KB |
Output is correct |
27 |
Correct |
2 ms |
1120 KB |
Output is correct |
28 |
Correct |
3 ms |
1884 KB |
Output is correct |
29 |
Correct |
2 ms |
860 KB |
Output is correct |
30 |
Correct |
2 ms |
1372 KB |
Output is correct |
31 |
Correct |
7 ms |
1816 KB |
Output is correct |
32 |
Correct |
12 ms |
2532 KB |
Output is correct |
33 |
Correct |
18 ms |
3228 KB |
Output is correct |
34 |
Correct |
18 ms |
7080 KB |
Output is correct |
35 |
Correct |
8 ms |
7504 KB |
Output is correct |
36 |
Correct |
18 ms |
7308 KB |
Output is correct |
37 |
Correct |
16 ms |
3788 KB |
Output is correct |
38 |
Correct |
21 ms |
7016 KB |
Output is correct |
39 |
Correct |
16 ms |
7500 KB |
Output is correct |
40 |
Correct |
20 ms |
3724 KB |
Output is correct |
41 |
Correct |
70 ms |
13572 KB |
Output is correct |
42 |
Correct |
166 ms |
69304 KB |
Output is correct |
43 |
Correct |
119 ms |
65572 KB |
Output is correct |
44 |
Correct |
264 ms |
70556 KB |
Output is correct |
45 |
Correct |
236 ms |
72392 KB |
Output is correct |
46 |
Correct |
161 ms |
31600 KB |
Output is correct |
47 |
Correct |
179 ms |
31728 KB |
Output is correct |
48 |
Correct |
229 ms |
71632 KB |
Output is correct |
49 |
Correct |
156 ms |
32024 KB |
Output is correct |
50 |
Correct |
155 ms |
30772 KB |
Output is correct |
51 |
Correct |
167 ms |
56136 KB |
Output is correct |
52 |
Correct |
232 ms |
57252 KB |
Output is correct |
53 |
Correct |
169 ms |
70876 KB |
Output is correct |
54 |
Correct |
243 ms |
66264 KB |
Output is correct |
55 |
Correct |
278 ms |
67808 KB |
Output is correct |