Submission #167509

#TimeUsernameProblemLanguageResultExecution timeMemory
167509faremyParachute rings (IOI12_rings)C++14
0 / 100
1318 ms86892 KiB
#include <algorithm> #include <vector> #include <iostream> const int MAXN = 1e6; int rings; std::vector<int> graph[MAXN]; int parent[MAXN]; int ccSize[MAXN]; int candidate = -1; int part = 0; int last = -1; bool isParticular[MAXN]; std::vector<int> listThree; std::vector<int> listMore; bool seen[MAXN]; void Init(int N_) { rings = N_; for (int iRing = 0; iRing < rings; iRing++) { parent[iRing] = iRing; ccSize[iRing] = 1; } } int find(int node) { if (node != parent[node]) parent[node] = find(parent[node]); return parent[node]; } void fillLists(int node) { if (seen[node]) return; seen[node] = true; if (graph[node].size() == 3) listThree.emplace_back(node); else if (graph[node].size() > 3) listMore.emplace_back(node); for (int next : graph[node]) fillLists(next); } int nogood(int node, int root) { if (seen[node]) return 0; seen[node] = true; int degOffset = 0; for (int next : graph[node]) if (next == root) degOffset = 1; if (graph[node].size() - degOffset == 3) return -1; int ans = (graph[node].size() - degOffset < 2); for (int next : graph[node]) { int sub = nogood(next, root); if (sub == -1) return -1; ans |= sub; } return ans; } int check(int node) { listThree.clear(); listMore.clear(); std::fill_n(seen, rings, false); fillLists(node); if (listThree.empty() && listMore.empty()) return ccSize[node]; if (listThree.size() > 3 || listMore.size() > 1 || (listMore.size() == 1 && listThree.size() > 0)) { candidate = -2; return 0; } if (listMore.size() == 1) { std::fill_n(seen, rings, false); seen[listMore[0]] = true; for (int start : graph[listMore[0]]) if (!seen[start] && nogood(start, listMore[0]) < 1) { candidate = -2; return 0; } return 1; } if (listThree.size() == 1) { std::fill_n(seen, rings, false); seen[listThree[0]] = true; int cyc = 0; for (int start : graph[listThree[0]]) { if (seen[start]) cyc++; else if (nogood(start, listThree[0]) < 1) { candidate = -2; return 0; } } if (cyc == 0) return 4; if (cyc == 1) return 3; return 1; } int ans = 0; for (int root : listThree) { std::fill_n(seen, rings, false); seen[root] = true; bool isInvalid = false; for (int start : graph[root]) if (!seen[start]) isInvalid |= (nogood(start, root) < 1); ans += !isInvalid; } if (ans == 0) candidate = -2; return ans; } void Link(int A, int B) { if (candidate == -2) return; int ccA = find(A); int ccB = find(B); graph[A].emplace_back(B); graph[B].emplace_back(A); if (ccA == ccB) { part += !isParticular[ccA]; isParticular[ccA] = true; last = -1; } else { if (ccSize[ccA] < ccSize[ccB]) std::swap(ccA, ccB); parent[ccB] = ccA; ccSize[ccA] += ccSize[ccB]; if (isParticular[ccA] && isParticular[ccB]) { part--; last = -1; } isParticular[ccA] |= isParticular[ccB]; if (graph[A].size() == 3 || graph[A].size() == 4 || graph[B].size() == 3 || graph[B].size() == 4) { part += !isParticular[ccA]; isParticular[ccA] = true; last = -1; } else if (graph[A].size() > 4 || graph[B].size() > 4) { isParticular[ccA] = true; } } if (isParticular[ccA] && candidate != -2) candidate = ccA; } int CountCritical() { if (candidate == -2) return 0; if (part == 0) return rings; if (part > 1) return 0; //if (last == -1) last = check(candidate); return last; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...