Submission #583738

#TimeUsernameProblemLanguageResultExecution timeMemory
583738drdilyorOne-Way Streets (CEOI17_oneway)C++17
100 / 100
380 ms46096 KiB
#if defined(ONPC) && !defined(_GLIBCXX_ASSERTIONS) #define _GLIBCXX_ASSERTIONS #endif #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/detail/standard_policies.hpp> #ifdef ONPC #include "t_debug.cpp" #else #define debug(...) 42 #endif #define allit(a) (a).begin(), (a).end() #define sz(a) ((int) (a).size()) using namespace std; using ll = long long; using vi = vector<int>; namespace pd = __gnu_pbds; template<typename K> using ordered_set = pd::tree<K, pd::null_type, less<int>, pd::rb_tree_tag, pd::tree_order_statistics_node_update>; template<typename... T> using gp_hash_table = pd::gp_hash_table<T...>;//simple using statement gives warnings const int INF = 1e9; const ll INFL = 1e18; const int N = 1e5; const int LOGN = 17; const int RANDOM = chrono::high_resolution_clock::now().time_since_epoch().count(); mt19937 rng(RANDOM); struct LCA { int n; vi parent[LOGN]; vi parentedgeix; vi depth; LCA(vector<vector<pair<int,int>>>& adj) { n = sz(adj); depth = vi(n, -1); parentedgeix = vi(n, -1); for (int i = 0; i < LOGN; i++) parent[i] = vi(n, -1); for (int i = 0; i < n; i++) if (depth[i] == -1) dfs(adj, i); for (int j = 1; j < LOGN; j++) { for (int i = 0; i < n; i++) { if (parent[j-1][i] != -1) parent[j][i] = parent[j-1][ parent[j-1][i] ]; } } } void dfs(vector<vector<pair<int,int>>>& adj, int i, int p = -1) { if (p ==-1) depth[i] = 0; for (auto [e, edgeix] : adj[i]) if (e != p) { depth[e] = depth[i]+1; parent[0][e] = i; parentedgeix[e] = edgeix; dfs(adj, e, i); } } int query(int a, int b) { if (depth[a] < depth[b]) swap(a, b); for (int j = LOGN-1; j >= 0; j--) { if (parent[j][a] == -1) continue; if (depth[parent[j][a]] >= depth[b]) a = parent[j][a]; } if (a == b) return a; for (int j = LOGN-1; j>= 0; j--) { if (parent[j][a] != -1 && parent[j][b] != -1 && parent[j][a] != parent[j][b]) { a = parent[j][a]; b = parent[j][b]; } } return parent[0][a]; } }; int solve() { int n, m; cin >> n >> m; vector<vector<pair<int,int>>> adj(n); vector<pair<int,int>> edges; set<pair<int,int>> edgeSet; set<pair<int,int>> neverBridge; for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; u--; v--; adj[u].emplace_back(v, i); adj[v].emplace_back(u, ~i); edges.emplace_back(u, v); pair<int,int> key = {min(u, v), max(u, v)}; if (edgeSet.count(key)) { neverBridge.insert(key); } edgeSet.insert(key); } vector<char> visited(n, false); vi tin(n, -1), low(n, -1); int timer = 0; set<pair<int,int>> bridges; function<void(int,int)> dfs = [&](int v, int p) { visited[v] = true; tin[v] = low[v] = timer++; for (auto [to, _] : adj[v]) { if (to == p) continue; if (visited[to]) { low[v] = min(low[v], tin[to]); } else { dfs(to, v); low[v] = min(low[v], low[to]); if (low[to] > tin[v]) { pair<int,int> key = {min(to, v), max(to, v)}; if (neverBridge.count(key)) continue; bridges.insert(key); } } } }; for (int i = 0; i < n; ++i) { if (!visited[i]) dfs(i, -1); } vector<vector<pair<int,int>>> ccadj; vi rootof(n, -1); int roots = 0; function<void(int, int)> dfsCC = [&](int i, int root) { if (rootof[i] != -1) return; rootof[i] = root; for (auto [e, edgeix] : adj[i]) { if (bridges.count({min(i,e), max(i,e)}) == 0) { dfsCC(e, root); } else { if (rootof[e] == -1) { roots++; ccadj.resize(ccadj.size()+1); dfsCC(e, roots-1); } ccadj[root].emplace_back(rootof[e], edgeix); } } }; for (int i = 0; i < n; i++) { if (rootof[i] == -1) { roots++; ccadj.resize(ccadj.size()+1); dfsCC(i, roots-1); } } debug(rootof, ccadj); LCA lca(ccadj); string res(edges.size(), 'B'); int q; cin >> q; vector<pair<int,int>> pathUp, pathDown; while (q--) { int from, to; cin >> from >> to; from = rootof[from-1], to = rootof[to-1]; int c = lca.query(from, to); assert(c != -1); pathUp.emplace_back(from, c); pathDown.emplace_back(to, c); } auto comp = [&](pair<int,int> a, pair<int,int> b) { return a.second < b.second; }; sort(allit(pathUp), comp); sort(allit(pathDown), comp); for (auto [from, c] : pathUp) { while (from != c) { int eix = lca.parentedgeix[from]; if (res[max(eix, ~eix)] != 'B') break; if (eix < 0) res[~eix] = 'R'; else res[eix] = 'L'; from = lca.parent[0][from]; } } for (auto [to, c] : pathDown) { while (to != c) { int eix = lca.parentedgeix[to]; if (res[max(eix, ~eix)] != 'B') break; if (eix < 0) res[~eix] = 'L'; else res[eix] = 'R'; to = lca.parent[0][to]; } } cout << res; return 0; } signed main() { cin.tie(0)->sync_with_stdio(0); int t = 1; #ifdef ONPC cin >> t; #endif while (t-- && cin) { if (solve()) break; #ifdef ONPC cout << "____________________" << endl; #endif } return 0; }

Compilation message (stderr)

oneway.cpp: In function 'int solve()':
oneway.cpp:10:24: warning: statement has no effect [-Wunused-value]
   10 |     #define debug(...) 42
      |                        ^~
oneway.cpp:159:5: note: in expansion of macro 'debug'
  159 |     debug(rootof, ccadj);
      |     ^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...