제출 #635928

#제출 시각아이디문제언어결과실행 시간메모리
635928Kanon수천개의 섬 (IOI22_islands)C++17
100 / 100
439 ms45116 KiB
#include <bits/stdc++.h> using namespace std; template <typename A, typename B> string to_string(pair<A, B> p); template <typename A, typename B, typename C> string to_string(tuple<A, B, C> p); template <typename A, typename B, typename C, typename D> string to_string(tuple<A, B, C, D> p); string to_string(const string& s) { return '"' + s + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(bool b) { return (b ? "true" : "false"); } string to_string(vector<bool> v) { bool first = true; string res = "{"; for (int i = 0; i < static_cast<int>(v.size()); i++) { if (!first) { res += ", "; } first = false; res += to_string(v[i]); } res += "}"; return res; } template <size_t N> string to_string(bitset<N> v) { string res = ""; for (size_t i = 0; i < N; i++) { res += static_cast<char>('0' + v[i]); } return res; } template <typename A> string to_string(A v) { bool first = true; string res = "{"; for (const auto &x : v) { if (!first) { res += ", "; } first = false; res += to_string(x); } res += "}"; return res; } template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } template <typename A, typename B, typename C> string to_string(tuple<A, B, C> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")"; } template <typename A, typename B, typename C, typename D> string to_string(tuple<A, B, C, D> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")"; } void debug_out() { cerr << endl; } template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); } #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__); struct edge { int from; int to; edge(){}; edge(int _from, int _to) : from(_from), to(_to){}; }; variant<bool, vector<int>> find_journey(int n, int m, vector<int> A, vector<int> B) { vector<edge> edges; vector<set<int>> g(n); vector<set<int>> rev_g(n); auto rev = [&](int e) { int u = edges[e].from, v = edges[e].to; g[u].erase(e); rev_g[v].erase(e); }; auto add = [&](int e) { int u = edges[e].from, v = edges[e].to; g[u].insert(e); rev_g[v].insert(e); }; for (int i = 0; i < m; i++) { edges.emplace_back(A[i], B[i]); add(i); } int st = 0; vector<int> trail; set<pair<int, int>> pos; for (int i = 0; i < n; i++) { pos.insert(make_pair(g[i].size(), i)); } while (true) { bool change = false; while (pos.size() && pos.begin()->first == 0) { int v = pos.begin()->second; pos.erase(pos.begin()); change = true; vector<int> make; for (int e : rev_g[v]) { make.push_back(e); } for (int e : make) { int u = edges[e].from; pos.erase(make_pair(g[u].size(), u)); rev(e); pos.insert(make_pair(g[u].size(), u)); } } while (g[st].size() < 2) { if (g[st].empty()) { return false; } vector<int> make; for (int e : rev_g[st]) { make.push_back(e); } for (int e : make) { if (trail.size() && e == trail.back()) { continue; } change = true; int u = edges[e].from; pos.erase(make_pair(g[u].size(), u)); rev(e); pos.insert(make_pair(g[u].size(), u)); } int e = *g[st].begin(); st = edges[e].to; trail.push_back(e); } if (!change) { break; } } vector<int> path; vector<int> cyc; vector<bool> was(n); vector<bool> in_queque(n); vector<int> que; vector<int> ed; function<bool(int)> dfs = [&](int v) { was[v] = true; in_queque[v] = true; que.push_back(v); for (int e : g[v]) { int u = edges[e].to; if (in_queque[u]) { bool done = false; for (int es : ed) { if (edges[es].from != u && !done) { path.push_back(es); } else { cyc.push_back(es); done = true; } } cyc.push_back(e); return true; } if (was[u]) { continue; } ed.push_back(e); if (dfs(u)) { return true; } ed.pop_back(); } in_queque[v] = false; que.pop_back(); return false; }; vector<int> path1, path2, cyc1, cyc2; if (!dfs(st)) { return false; } path1 = path; cyc1 = cyc; fill(in_queque.begin(), in_queque.end(), false); fill(was.begin(), was.end(), false); path.clear(); cyc.clear(); que.clear(); ed.clear(); for (int e : cyc1) { rev(e); swap(edges[e].from, edges[e].to); add(e); } for (int e : cyc1) { int v = edges[e].from; vector<int> r; if (v != st) { for (int es : g[v]) { if (es != e) { r.push_back(es); } } } else { assert(path1.empty()); } for (int es : r) { rev(es); } } if (path1.empty()) { for (int e : cyc1) { int v = edges[e].from; if (v == st) { for (int es : g[v]) { if (es == e) { continue; } int u = edges[es].to; vector<int> make; for (int E : g[v]) { if (E != e) { make.push_back(E); } } for (int E : make) { rev(E); } assert(dfs(u)); path2 = path; cyc2 = cyc; path2.insert(path2.begin(), es); break; } assert(cyc2.size() && path2.size()); break; } } } else { int e = path1[0]; assert(edges[e].from == st); rev(e); assert(dfs(st)); path2 = path; cyc2 = cyc; } vector<int> ret; auto add_way = [&](vector<int> &a) { for (int e : a) { ret.push_back(e); } reverse(a.begin(), a.end()); }; bool same = false; { int sam = edges[cyc1[0]].from; for (int e : cyc2) { int v = edges[e].from; if (v == sam) { same = true; } } } add_way(trail); for (int rot = 0; rot < (same ? 1 : 2); rot++) { add_way(path1); add_way(cyc1); add_way(path1); add_way(path2); add_way(cyc2); add_way(path2); } add_way(trail); return ret; }
#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...