This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
set<array<int, 2>> S2;
vector<vector<int>> adj;
struct UnionFind {
vector<int> root;
int cypt = -1;
bool deg3 = false;
int pt = -1;
void init(int N) {
root.resize(N);
fill(root.begin(),root.end(),-1);
}
void bye() {
root.clear();
root.shrink_to_fit();
}
int Find(int n) {
if(root[n]<0) return n;
int r = Find(root[n]);
root[n] = r;
return r;
}
void Merge(int x, int y) {
if(deg3) return;
int d1 = adj[x].size() - (S2.find({min(pt, x), max(pt, x)})!=S2.end()?1:0);
int d2 = adj[y].size() - (S2.find({min(pt, y), max(pt, y)})!=S2.end()?1:0);
if(d1>=3) deg3 = true;
if(d2>=3) deg3 = true;
//if(deg3) bye();
if(deg3) return;
x = Find(x), y = Find(y);
if(x==y) {
if(cypt==-1) cypt = x;
else cypt = -2;
return;
}
if(root[x]>root[y]) swap(x, y);
root[x] += root[y];
root[y] = x;
}
};
int N;
int cnt;
set<int> S;
UnionFind U;
UnionFind UF[4];
map<int, int> id;
int id2[5];
bool idcnt = false;
void Init(int _N) {
N = _N;
adj.resize(N);
int i;
for(i=0;i<N;i++) S.insert(i);
if(S.size() <= 4 && !idcnt) {
idcnt = true;
int ck = 0;
for(int n : S) {
id[n] = ck;
UF[ck].pt = n;
id2[ck] = n;
ck++;
UF[ck].init(N);
}
}
else U.init(N);
}
void Link(int x, int y) {
adj[x].push_back(y);
adj[y].push_back(x);
S2.insert({min(x, y), max(x, y)});
if(adj[x].size() == 3) {
set<int> S2;
S2.insert(x);
for(int n : adj[x]) S2.insert(n);
for(int n : S2) {
if(S.find(n) == S.end()) S2.erase(n);
}
S = S2;
}
if(adj[x].size() >= 4) {
if(S.find(x) == S.end()) S = set<int> {};
else S = set<int>{x};
}
if(adj[y].size() == 3) {
set<int> S2;
S2.insert(y);
for(int n : adj[y]) S2.insert(n);
for(int n : S2) {
if(S.find(n) == S.end()) S2.erase(n);
}
S = S2;
}
if(adj[y].size() >= 4) {
if(S.find(y) == S.end()) S = set<int> {};
else S = set<int>{y};
}
bool now = false;
if(S.size() <= 4 && !idcnt) {
idcnt = true;
now = true;
int ck = 0;
U.bye();
for(int n : S) {
id[n] = ck;
id2[ck] = n;
UF[ck].pt = n;
UF[ck].init(N);
for(auto k : S2) {
if(k[0] != n && k[1] != n) {
UF[ck].Merge(k[0], k[1]);
}
}
ck++;
}
}
if(!idcnt) U.Merge(x, y);
if(idcnt && !now) {
for(int i=0;i<4;i++) {
if(x != id2[i] && y != id2[i]) {
UF[i].Merge(x, y);
}
}
}
}
int CountCritical() {
if(S.size() == 0) return 0;
if(!idcnt) {
//assert(!U.deg3);
if(U.cypt==-1) return N;
else if(U.cypt==-2) return 0;
else return -U.root[U.Find(U.cypt)];
}
else {
int cnt = 0;
for(int n : S) {
if(!UF[id[n]].deg3 && UF[id[n]].cypt == -1) cnt++;
}
return cnt;
}
}
/*
signed main() {
cin.sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int N, L;
cin >> N >> L;
Init(N);
while(L--) {
int a;
cin >> a;
if(a==-1) cout << CountCritical() << '\n';
else {
int b;
cin >> b;
Link(a, b);
}
}
}
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |