Submission #1011362

#TimeUsernameProblemLanguageResultExecution timeMemory
1011362NValchanovOne-Way Streets (CEOI17_oneway)C++17
100 / 100
184 ms104332 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; const ll MAXN = 1e6 + 10; const ll MAXM = 1e6 + 10; const ll MAXP = 1e6 + 10; const ll MAXLOG = 30; struct edge { ll u,v,idx; edge(){}; edge(ll _u, ll _v, ll _idx) { u = _u; v = _v; idx = _idx; } }; struct path { ll u,v,l; path(){}; path(ll _u, ll _v, ll _l) { u = _u; v = _v; l = _l; } }; ll n,m,p; edge edges[MAXM]; vector < edge > adj[MAXN]; vector < edge > badj[MAXN]; vector < pair < ll, ll > > order_paths; path paths[MAXP]; bool is_bridge[MAXM]; ll bcomp[MAXN]; char ans[MAXN]; ll lift[MAXN][MAXLOG]; bool visited[MAXN]; ll direction[MAXN]; ll depth[MAXN]; edge parent[MAXN]; ll low[MAXN]; ll tin[MAXN]; ll tim; ll comp_cnt; void find_bridges(ll u, ll par_edge) { tin[u] = low[u] = ++tim; for(edge nb : adj[u]) { ll v = nb.v; ll idx = nb.idx; if(idx == par_edge) continue; if(tin[v]) { low[u] = min(low[u], tin[v]); } else { find_bridges(v, idx); low[u] = min(low[u], low[v]); if(tin[u] < low[v]) is_bridge[idx] = true; } } } void find_components(ll u, ll comp) { visited[u] = true; bcomp[u] = comp; for(edge nb : adj[u]) { ll v = nb.v; ll idx = nb.idx; if(!visited[v] && !is_bridge[idx]) find_components(v, comp); } } void dfs(ll u, ll par, ll par_edge) { /// cout << u << " " << par << " " << par_edge << endl; depth[u] = depth[par] + 1; parent[u].v = par; parent[u].idx = par_edge; lift[u][0] = par; for(edge nb : badj[u]) { ll v = nb.v; ll idx = nb.idx; if(v != par) dfs(v, u, idx); } } void fill_lift() { for(int j = 1; j < MAXLOG; j++) { for(int i = 1; i <= comp_cnt; i++) { lift[i][j] = lift[lift[i][j - 1]][j - 1]; } } /** for(int j = 0; j < MAXLOG; j++) { for(int i = 1; i <= comp_cnt; i++) { cout << lift[i][j] << " "; } cout << endl; } */ } ll find_lca(ll u, ll v) { if(depth[u] < depth[v]) swap(u, v); ll diff = depth[u] - depth[v]; for(int j = MAXLOG - 1; j >= 0; j--) { if(diff >= (1LL << j)) { diff -= (1LL << j); u = lift[u][j]; } } if(u == v) return u; for(int j = MAXLOG - 1; j >= 0; j--) { if(lift[u][j] != lift[v][j]) { u = lift[u][j]; v = lift[v][j]; } } return lift[u][0]; } void direct_edges(ll from, ll to, ll type) { if(from == to) return; if(direction[from] == 0) { direction[from] = type; ll u = parent[from].v; ll idx = parent[from].idx; edge e = edges[idx]; ll bu = bcomp[e.u]; ll bv = bcomp[e.v]; if(type == 1) { if(bu == from && bv == u) ans[idx] = 'R'; else ans[idx] = 'L'; } else if(type == 2) { if(bu == u && bv == from) ans[idx] = 'R'; else ans[idx] = 'L'; } else { assert(false); } direct_edges(u, to, type); } else { if(direction[from] != type) { cout << "IMPOSSIBLE" << endl; assert(false); } } } void read() { cin >> n >> m; for(int i = 1; i <= m; i++) { ll u,v; cin >> u >> v; edge e = edge(u,v,i); edges[i] = e; adj[u].push_back(e); swap(e.u, e.v); adj[v].push_back(e); } } void make_bridge_graph() { for(int i = 1; i <= n; i++) { if(!tin[i]) find_bridges(i, 0); } for(int i = 1; i <= n; i++) { if(!visited[i]) find_components(i, ++comp_cnt); } /** for(int i = 1; i <= n; i++) { cout << "Vertex " << i << " is in bridge component " << bcomp[i] << endl; } */ for(edge e : edges) { ll u = e.u; ll v = e.v; ll idx = e.idx; if(!is_bridge[e.idx]) continue; ll bu = bcomp[u]; ll bv = bcomp[v]; badj[bu].push_back(edge(bu, bv, idx)); badj[bv].push_back(edge(bv, bu, idx)); } /** for(int i = 1; i <= comp_cnt; i++) { cout << "Neighbours of " << i << " are : " << endl; for(edge nb : badj[i]) { cout << " - " << nb.v << endl; } } */ } void make_lift() { for(int i = 1; i <= comp_cnt; i++) { if(!depth[i]) { dfs(i, 0, 0); } } /* for(int i = 1; i <= comp_cnt; i++) { cout << "Depth of bridge component " << i << " is " << depth[i] << endl; } */ fill_lift(); } void init_ans() { for(int i = 1; i <= m; i++) { ans[i] = 'B'; } } void process_paths() { cin >> p; for(int i = 1; i <= p; i++) { ll u,v; cin >> u >> v; u = bcomp[u]; v = bcomp[v]; ll l = find_lca(u,v); paths[i] = path(u, v, l); order_paths.push_back(make_pair(depth[l], i)); } } void solve() { sort(order_paths.begin(), order_paths.end()); for(pair < ll, ll > cur_path : order_paths) { ll idx = cur_path.second; ll u = paths[idx].u; ll v = paths[idx].v; ll l = paths[idx].l; direct_edges(u, l, 1); direct_edges(v, l, 2); } } void print() { for(int i = 1; i <= m; i++) { cout << ans[i]; } cout << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); read(); make_bridge_graph(); make_lift(); init_ans(); process_paths(); solve(); print(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...