#include <iostream>
#include <vector>
using namespace std;
const int maxN = 1'000'000;
struct disjoint_set
{
int S;
vector<int> parent;
vector<int> subtree;
disjoint_set()
{
;
}
disjoint_set(int s)
{
S = s;
parent = vector<int>(S);
subtree = vector<int>(S);
for(int i = 0; i < S; i++)
{
parent[i] = i;
subtree[i] = 1;
}
}
int root(int u)
{
int v = u;
while(parent[v] != v) v = parent[v];
parent[u] = v;
return v;
}
bool connected(int u, int v)
{
return root(u) == root(v);
}
void join(int u, int v)
{
u = root(u);
v = root(v);
if(u == v) return;
if(subtree[u] < subtree[v]) swap(u, v);
subtree[u] += subtree[v];
parent[v] = u;
}
};
const int X = 0;
const int Y = 1;
const int Z = 2;
//general
int state = X;
int N;
//state == X
vector<int> edge[maxN];
disjoint_set prevDSU;
int degree(int u)
{
return (int)edge[u].size();
}
//state == Y
int cyclic_count = 0;
vector<bool> cyclic(maxN, 0);
void go_to_Y(int label)
{
// cerr << "switching to Y\n";
state = Y;
for(int i = 0; i < N; i++)
{
if(prevDSU.connected(i, label))
{
cyclic[i] = 1;
cyclic_count++;
}
}
}
//state == Z
int Zsize;
vector<int> Z_critical;
vector< vector<int> > Z_degree;
vector<disjoint_set> DSU;
vector<bool> good;
void Z_link(int A, int B)
{
for(int q = 0; q < Zsize; q++)
{
if(!good[q]) continue;
int z = Z_critical[q];
if(A == z || B == z)
{
continue;
}
// cerr << "link " << A << ' ' << B << " in DSU " << q << " ( " << Z_critical[q] << ") \n";
// cerr << DSU[q].root(A) << ' ' << DSU[q].root(B) << '\n';
if(DSU[q].connected(A, B))
{
// cerr << "DSU " << q << " (" << Z_critical[q] << ") made not good by cycle\n";
good[q] = 0;
}
Z_degree[q][A]++;
Z_degree[q][B]++;
// if(q == 0)
// cerr << "edge " << A << ' ' << B << '\n';
if(Z_degree[q][A] > 2 || Z_degree[q][B] > 2)
{
// cerr << "DSU " << q << " (" << Z_critical[q] << ") made not good by high degree\n";
good[q] = 0;
}
DSU[q].join(A, B);
}
}
void go_to_Z(vector<int> V)
{
// cerr << "switching to Z\n";
// for(int v:V) cerr << v << ' ';
// cerr << '\n';
// cerr << (int)V.size() << '\n';
state = Z;
Zsize = V.size();
Z_critical = V;
Z_degree = vector< vector<int> >(Zsize, vector<int>(N, 0));
DSU = vector<disjoint_set>(Zsize, disjoint_set(N));
good = vector<bool>(Zsize, 1);
for(int u = 0; u < N; u++)
{
for(int v: edge[u])
{
// cerr << "edge list " << u << ' ' << v << '\n';
if(v < u) continue;
Z_link(u, v);
}
}
// for(int q = 0; q < 4; q++)
// {
// for(int i = 0; i < N; i++) cerr << Z_degree[q][i] << ' ';
// cerr << '\n';
// }
}
void Init(int N_)
{
N = N_;
prevDSU = disjoint_set(N);
}
int CountCritical()
{
if(state == X) return N;
else if(state == Y)
{
return cyclic_count;
}
else// if(state == Z)
{
int res = 0;
for(int q = 0; q < good.size(); q++)
{
res += good[q];
// if(good[q]) cerr << "good = " << Z_critical[q] << '\n';
}
return res;
}
}
void Link(int A, int B)
{
if(state == X)
{
if(!prevDSU.connected(A, B))
{
if(degree(A) <= 1 && degree(B) <= 1)
{
prevDSU.join(A, B);
edge[A].push_back(B);
edge[B].push_back(A);
}
else if(degree(A) <= 1)
{
vector<int> V = edge[B];
V.push_back(A);
V.push_back(B);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else if(degree(B) <= 1)
{
vector<int> V = edge[A];
V.push_back(A);
V.push_back(B);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else
{
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z({A, B});
}
}
else
{
if(degree(A) <= 1 && degree(B) <= 1)
{
// cerr << "case U\n";
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Y(A);
}
else if(degree(A) <= 1)
{
// cerr << "case V\n";
vector<int> V = edge[B];
V.push_back(A);
V.push_back(B);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else if(degree(B) <= 1)
{
// cerr << "case W\n";
vector<int> V = edge[A];
V.push_back(A);
V.push_back(B);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else
{
// cerr << "case T\n";
vector<int> V{A, B};
for(int e: edge[A])
for(int f: edge[B])
if(e == f)
V.push_back(e);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
}
}
else if(state == Y)
{
if(cyclic[A] && cyclic[B])
{
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z({A, B});
}
else if(cyclic[A] && !cyclic[B])
{
vector<int> V = edge[A];
V.push_back(A);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else if(cyclic[B] && !cyclic[A])
{
vector<int> V = edge[B];
V.push_back(B);
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z(V);
}
else
{
if(!prevDSU.connected(A, B))
{
if(degree(A) <= 1 && degree(B) <= 1)
{
edge[A].push_back(B);
edge[B].push_back(A);
prevDSU.join(A, B);
}
else
{
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z({});
}
}
else
{
edge[A].push_back(B);
edge[B].push_back(A);
go_to_Z({});
}
}
}
else if(state == Z)
{
edge[A].push_back(B);
edge[B].push_back(A);
Z_link(A, B);
}
// cerr << CountCritical() << '\n';
}
Compilation message
rings.cpp: In function 'int CountCritical()':
rings.cpp:189:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<bool>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
189 | for(int q = 0; q < good.size(); q++)
| ~~^~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
23884 KB |
Output is correct |
2 |
Correct |
15 ms |
24324 KB |
Output is correct |
3 |
Correct |
16 ms |
24300 KB |
Output is correct |
4 |
Correct |
14 ms |
23884 KB |
Output is correct |
5 |
Correct |
15 ms |
24012 KB |
Output is correct |
6 |
Correct |
16 ms |
24120 KB |
Output is correct |
7 |
Correct |
14 ms |
24140 KB |
Output is correct |
8 |
Correct |
18 ms |
24056 KB |
Output is correct |
9 |
Correct |
19 ms |
24396 KB |
Output is correct |
10 |
Correct |
16 ms |
24396 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
336 ms |
45040 KB |
Output is correct |
2 |
Correct |
1073 ms |
94212 KB |
Output is correct |
3 |
Correct |
811 ms |
107296 KB |
Output is correct |
4 |
Correct |
948 ms |
64356 KB |
Output is correct |
5 |
Correct |
896 ms |
64460 KB |
Output is correct |
6 |
Correct |
837 ms |
63380 KB |
Output is correct |
7 |
Correct |
779 ms |
106968 KB |
Output is correct |
8 |
Correct |
1484 ms |
110176 KB |
Output is correct |
9 |
Correct |
1680 ms |
118420 KB |
Output is correct |
10 |
Correct |
646 ms |
70476 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
23884 KB |
Output is correct |
2 |
Correct |
15 ms |
24324 KB |
Output is correct |
3 |
Correct |
16 ms |
24300 KB |
Output is correct |
4 |
Correct |
14 ms |
23884 KB |
Output is correct |
5 |
Correct |
15 ms |
24012 KB |
Output is correct |
6 |
Correct |
16 ms |
24120 KB |
Output is correct |
7 |
Correct |
14 ms |
24140 KB |
Output is correct |
8 |
Correct |
18 ms |
24056 KB |
Output is correct |
9 |
Correct |
19 ms |
24396 KB |
Output is correct |
10 |
Correct |
16 ms |
24396 KB |
Output is correct |
11 |
Correct |
16 ms |
24396 KB |
Output is correct |
12 |
Correct |
22 ms |
24768 KB |
Output is correct |
13 |
Correct |
19 ms |
24852 KB |
Output is correct |
14 |
Correct |
17 ms |
24748 KB |
Output is correct |
15 |
Correct |
18 ms |
25256 KB |
Output is correct |
16 |
Correct |
18 ms |
24508 KB |
Output is correct |
17 |
Correct |
17 ms |
24780 KB |
Output is correct |
18 |
Correct |
18 ms |
25540 KB |
Output is correct |
19 |
Correct |
17 ms |
24440 KB |
Output is correct |
20 |
Correct |
19 ms |
24928 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
23884 KB |
Output is correct |
2 |
Correct |
15 ms |
24324 KB |
Output is correct |
3 |
Correct |
16 ms |
24300 KB |
Output is correct |
4 |
Correct |
14 ms |
23884 KB |
Output is correct |
5 |
Correct |
15 ms |
24012 KB |
Output is correct |
6 |
Correct |
16 ms |
24120 KB |
Output is correct |
7 |
Correct |
14 ms |
24140 KB |
Output is correct |
8 |
Correct |
18 ms |
24056 KB |
Output is correct |
9 |
Correct |
19 ms |
24396 KB |
Output is correct |
10 |
Correct |
16 ms |
24396 KB |
Output is correct |
11 |
Correct |
16 ms |
24396 KB |
Output is correct |
12 |
Correct |
22 ms |
24768 KB |
Output is correct |
13 |
Correct |
19 ms |
24852 KB |
Output is correct |
14 |
Correct |
17 ms |
24748 KB |
Output is correct |
15 |
Correct |
18 ms |
25256 KB |
Output is correct |
16 |
Correct |
18 ms |
24508 KB |
Output is correct |
17 |
Correct |
17 ms |
24780 KB |
Output is correct |
18 |
Correct |
18 ms |
25540 KB |
Output is correct |
19 |
Correct |
17 ms |
24440 KB |
Output is correct |
20 |
Correct |
19 ms |
24928 KB |
Output is correct |
21 |
Correct |
33 ms |
25676 KB |
Output is correct |
22 |
Correct |
54 ms |
26672 KB |
Output is correct |
23 |
Correct |
51 ms |
27468 KB |
Output is correct |
24 |
Correct |
54 ms |
31268 KB |
Output is correct |
25 |
Correct |
31 ms |
30400 KB |
Output is correct |
26 |
Correct |
64 ms |
32108 KB |
Output is correct |
27 |
Correct |
63 ms |
28600 KB |
Output is correct |
28 |
Correct |
59 ms |
31476 KB |
Output is correct |
29 |
Correct |
47 ms |
31548 KB |
Output is correct |
30 |
Correct |
72 ms |
28872 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
23884 KB |
Output is correct |
2 |
Correct |
15 ms |
24324 KB |
Output is correct |
3 |
Correct |
16 ms |
24300 KB |
Output is correct |
4 |
Correct |
14 ms |
23884 KB |
Output is correct |
5 |
Correct |
15 ms |
24012 KB |
Output is correct |
6 |
Correct |
16 ms |
24120 KB |
Output is correct |
7 |
Correct |
14 ms |
24140 KB |
Output is correct |
8 |
Correct |
18 ms |
24056 KB |
Output is correct |
9 |
Correct |
19 ms |
24396 KB |
Output is correct |
10 |
Correct |
16 ms |
24396 KB |
Output is correct |
11 |
Correct |
336 ms |
45040 KB |
Output is correct |
12 |
Correct |
1073 ms |
94212 KB |
Output is correct |
13 |
Correct |
811 ms |
107296 KB |
Output is correct |
14 |
Correct |
948 ms |
64356 KB |
Output is correct |
15 |
Correct |
896 ms |
64460 KB |
Output is correct |
16 |
Correct |
837 ms |
63380 KB |
Output is correct |
17 |
Correct |
779 ms |
106968 KB |
Output is correct |
18 |
Correct |
1484 ms |
110176 KB |
Output is correct |
19 |
Correct |
1680 ms |
118420 KB |
Output is correct |
20 |
Correct |
646 ms |
70476 KB |
Output is correct |
21 |
Correct |
16 ms |
24396 KB |
Output is correct |
22 |
Correct |
22 ms |
24768 KB |
Output is correct |
23 |
Correct |
19 ms |
24852 KB |
Output is correct |
24 |
Correct |
17 ms |
24748 KB |
Output is correct |
25 |
Correct |
18 ms |
25256 KB |
Output is correct |
26 |
Correct |
18 ms |
24508 KB |
Output is correct |
27 |
Correct |
17 ms |
24780 KB |
Output is correct |
28 |
Correct |
18 ms |
25540 KB |
Output is correct |
29 |
Correct |
17 ms |
24440 KB |
Output is correct |
30 |
Correct |
19 ms |
24928 KB |
Output is correct |
31 |
Correct |
33 ms |
25676 KB |
Output is correct |
32 |
Correct |
54 ms |
26672 KB |
Output is correct |
33 |
Correct |
51 ms |
27468 KB |
Output is correct |
34 |
Correct |
54 ms |
31268 KB |
Output is correct |
35 |
Correct |
31 ms |
30400 KB |
Output is correct |
36 |
Correct |
64 ms |
32108 KB |
Output is correct |
37 |
Correct |
63 ms |
28600 KB |
Output is correct |
38 |
Correct |
59 ms |
31476 KB |
Output is correct |
39 |
Correct |
47 ms |
31548 KB |
Output is correct |
40 |
Correct |
72 ms |
28872 KB |
Output is correct |
41 |
Correct |
217 ms |
39840 KB |
Output is correct |
42 |
Correct |
812 ms |
95844 KB |
Output is correct |
43 |
Correct |
292 ms |
87004 KB |
Output is correct |
44 |
Correct |
595 ms |
114676 KB |
Output is correct |
45 |
Correct |
757 ms |
108396 KB |
Output is correct |
46 |
Correct |
622 ms |
74196 KB |
Output is correct |
47 |
Correct |
779 ms |
69240 KB |
Output is correct |
48 |
Correct |
454 ms |
101608 KB |
Output is correct |
49 |
Correct |
583 ms |
67632 KB |
Output is correct |
50 |
Correct |
610 ms |
67296 KB |
Output is correct |
51 |
Correct |
323 ms |
78556 KB |
Output is correct |
52 |
Correct |
511 ms |
88720 KB |
Output is correct |
53 |
Correct |
457 ms |
102016 KB |
Output is correct |
54 |
Correct |
1288 ms |
104992 KB |
Output is correct |
55 |
Correct |
1082 ms |
111964 KB |
Output is correct |