제출 #1267717

#제출 시각아이디문제언어결과실행 시간메모리
1267717LucaLucaM열쇠 (IOI21_keys)C++20
100 / 100
2772 ms104656 KiB
#include <iostream> #include <vector> #include <cassert> #include <algorithm> #include <set> // https://mzhang2021.github.io/cp-blog/library/ struct SCC { int n; std::vector<std::vector<int>> g, gg; std::vector<int> order, cur; std::vector<bool> vis; std::vector<int> root; void init(int _n) { n = _n; g.resize(n); gg.resize(n); vis.assign(n, false); root.resize(n); order.clear(); cur.clear(); for (int i = 0; i < n; i++) { g[i].clear(); gg[i].clear(); } } void addEdge(int u, int v) { g[u].push_back(v); gg[v].push_back(u); } void dfs0(int u) { vis[u] = true; for (int v : g[u]) { if (!vis[v]) { dfs0(v); } } order.push_back(u); } void dfs(int u) { vis[u] = true; cur.push_back(u); for (int v : gg[u]) { if (!vis[v]) { dfs(v); } } } void build() { vis.assign(n, false); for (int i = 0; i < n; i++) { if (!vis[i]) { dfs0(i); } } vis.assign(n, false); std::reverse(order.begin(), order.end()); for (int u : order) { if (!vis[u]) { cur.clear(); dfs(u); for (int v : cur) { root[v] = cur[0]; } } } } }; std::vector<int> find_reachable(std::vector<int> a, std::vector<int> U, std::vector<int> V, std::vector<int> C) { int n = (int) a.size(); int m = (int) U.size(); U.resize(2 * m); V.resize(2 * m); C.resize(2 * m); for (int i = m; i < 2 * m; i++) { U[i] = V[i - m]; V[i] = U[i - m]; C[i] = C[i - m]; } m *= 2; std::vector<int> root(n); for (int i = 0; i < n; i++) { root[i] = i; } SCC g; for (int phase = 0; phase < 20; phase++) { std::vector<std::set<int>> keys(n); for (int i = 0; i < n; i++) { keys[root[i]].insert(a[i]); } g.init(n); for (int i = 0; i < m; i++) { int u = U[i], v = V[i]; int c = C[i]; if (root[u] == root[v] || keys[root[u]].count(c)) { g.addEdge(u, v); } } g.build(); for (int i = 0; i < n; i++) { root[i] = g.root[i]; } } std::vector<int> sz(n, 0); for (int i = 0; i < n; i++) { sz[root[i]]++; } std::vector<bool> hasOut(n, false); std::vector<std::set<int>> keys(n); for (int i = 0; i < n; i++) { keys[root[i]].insert(a[i]); } for (int i = 0; i < m; i++) { int u = U[i], v = V[i]; int c = C[i]; if (root[u] != root[v] && keys[root[u]].count(c)) { hasOut[root[u]] = true; } } int minSize = n; for (int i = 0; i < n; i++) { if (!hasOut[root[i]]) { minSize = std::min(minSize, sz[root[i]]); } } std::vector<int> ret(n, 0); for (int i = 0; i < n; i++) { if (!hasOut[root[i]]) { if (sz[root[i]] == minSize) { 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...