Submission #1304157

#TimeUsernameProblemLanguageResultExecution timeMemory
1304157rxlfd314열쇠 (IOI21_keys)C++17
0 / 100
2 ms572 KiB
#include "keys.h" #include <bits/stdc++.h> using namespace std; using ll = long long; using ari2 = array<int, 2>; using ari3 = array<int, 3>; using arl2 = array<ll, 2>; using arl3 = array<ll, 3>; template <class T> using vt = vector<T>; #define all(x) begin(x), end(x) #define size(x) (int((x).size())) #define REP(a,b,c,d) for(int a=(b);(d)>0?a<=(c):a>=(c);a+=(d)) #define FOR(a,b,c) REP(a,b,c,1) #define ROF(a,b,c) REP(a,b,c,-1) struct DSU { vt<int> uf, root; DSU(const int n) : uf(n, -1), root(n) { iota(all(root), 0); } int find(const int i) { return uf[i] < 0 ? i : uf[i] = find(uf[i]); } int get_root(const int i) { return root[find(i)]; } void unite(int a, int b) { if ((a = find(a)) == (b = find(b))) return; if (uf[a] > uf[b]) swap(a, b), swap(root[a], root[b]); uf[a] += uf[b]; uf[b] = a; root[b] = root[a]; } }; vt<int> find_reachable(const vt<int> R, const vt<int> U, const vt<int> V, const vt<int> C) { const int N = size(R), M = size(U); vt<vt<ari2>> adj(N); FOR(i, 0, M - 1) { adj[U[i]].push_back({V[i], C[i]}); adj[V[i]].push_back({U[i], C[i]}); } DSU uf(N); bool flag = true; unordered_set<int> ans, p_ans; const auto check = [&](const int x, const bool ret_option) { vt<int> seen(N), key(N); vt<vt<int>> blocked(N); queue<int> qu; qu.push(x); seen[x] = key[R[x]] = 1; while (size(qu)) { const int i = qu.front(); qu.pop(); if (!ret_option) p_ans.insert(i); for (const auto &[j, c] : adj[i]) { if (seen[j]) continue; if (key[c]) { if (uf.find(j) != uf.find(x)) { assert(ret_option); return uf.find(j); } qu.push(j); seen[j] = key[R[j]] = 1; } else { blocked[c].push_back(j); } } for (const auto &j : blocked[R[i]]) if (!seen[j]) { if (uf.find(j) != uf.find(x)) { assert(ret_option); return uf.find(j); } seen[j] = key[R[j]] = 1; qu.push(j); } blocked[R[i]].clear(); } return -1; }; while (flag) { flag = false; vt<ari2> pairs; FOR(i, 0, N - 1) { if (uf.find(i) != i) continue; const int j = check(i, 1); if (j >= 0) pairs.push_back({i, j}), flag = true; } for (const auto &[a, b] : pairs) uf.unite(b, a); } int cur = INT_MAX; FOR(i, 0, N - 1) { if (uf.get_root(i) != i) continue; check(i, 0); if (size(p_ans) < cur) ans.clear(); if (size(p_ans) <= cur) cur = size(p_ans), ans.insert(all(p_ans)); p_ans.clear(); } vt<int> ret(N); for (const auto &i : ans) ret[i] = 1; 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...