제출 #962835

#제출 시각아이디문제언어결과실행 시간메모리
962835LucaIlieOne-Way Streets (CEOI17_oneway)C++17
100 / 100
484 ms145984 KiB
#include <bits/stdc++.h> using namespace std; struct edge { int u, v; bool operator == ( const edge &x ) const { return (u == x.u && v == x.v) || (u == x.v && u == x.u); } bool operator != ( const edge &x ) const { return !(edge{ u, v } == x); } }; const int none = 0; const int up = 1; const int down = 2; const int MAX_N = 3e5; const int MAX_LOG_N = 18; const int MAX_M = 3e5; bool vis[MAX_N + 1], isInBiconex[MAX_N + 1]; int depth[MAX_N + 1], climbDepth[MAX_N + 1], countEdges[MAX_N + 1], vertexArt[MAX_N + 1], vertexBic[MAX_N + 1], biconex[MAX_N + 1], depthArb[MAX_N + 1], parent[MAX_LOG_N + 1][MAX_N + 1], art[MAX_N + 1], dir[MAX_N + 1]; vector<int> adj[MAX_N + 1], arbAdj[MAX_N + 1]; edge edges[MAX_M]; vector<int> articulation; vector<vector<int>> biconexe; unordered_map<int, bool> direction[MAX_N + 1]; vector<edge> edgeStack; unordered_map<int, int> frecvEdges[MAX_N + 1]; void findBiconexe( int u, int p ) { vis[u] = true; depth[u] = depth[p] + 1; climbDepth[u] = depth[u]; int c = 0; for ( int v: adj[u] ) { if ( v == p ) continue; if ( vis[v] ) { if ( depth[v] < depth[u] ) { edgeStack.push_back( { u, v } ); climbDepth[u] = min( climbDepth[u], depth[v] ); } } else { edgeStack.push_back( { u, v } ); c++; findBiconexe( v, u ); climbDepth[u] =min( climbDepth[u], climbDepth[v] ); if ( climbDepth[v] >= depth[u] ) { biconexe.push_back( {} ); if ( p != 0 ) articulation.push_back( u ); edge e; do { e = edgeStack.back(); edgeStack.pop_back(); countEdges[biconexe.size() - 1] += frecvEdges[e.u][e.v] + frecvEdges[e.v][e.u]; if ( !isInBiconex[e.u] ) { biconexe.back().push_back( e.u ); isInBiconex[e.u] = true; } if ( !isInBiconex[e.v] ) { biconexe.back().push_back( e.v ); isInBiconex[e.v] = true; } } while ( e != edge{ u, v } ); for ( int w: biconexe.back() ) isInBiconex[w] = false; } } } if ( p == 0 && c > 1 ) articulation.push_back( u ); } void dfs( int u, int p ) { vis[u] = true; parent[0][u] = p; depthArb[u] = depthArb[p] + 1; for ( int v: arbAdj[u] ) { if ( v == p ) continue; dfs( v, u ); } } void initLca( int n ) { for ( int p = 1; p <= MAX_LOG_N; p++ ) { for ( int v = 1; v <= n; v++ ) parent[p][v] = parent[p - 1][parent[p - 1][v]]; } } int lca( int u, int v ) { if ( depthArb[u] > depthArb[v] ) swap( u, v ); for ( int p = MAX_LOG_N; p >= 0; p-- ) { if ( depthArb[parent[p][v]] >= depthArb[u] ) v = parent[p][v]; } if ( u == v ) return u; for ( int p = MAX_LOG_N; p >= 0; p-- ) { if ( parent[p][u] != parent[p][v] ) { u = parent[p][u]; v = parent[p][v]; } } return parent[0][u]; } int updateUp[MAX_N + 1], dpUp[MAX_N + 1], updateDown[MAX_N + 1], dpDown[MAX_N + 1]; void calcUpDown( int u, int p ) { vis[u] = true; dpUp[u] = updateUp[u]; dpDown[u] = updateDown[u]; for ( int v: arbAdj[u] ) { if ( v == p ) continue; calcUpDown( v, u ); dpUp[u] += dpUp[v]; dpDown[u] += dpDown[v]; } if ( dpUp[u] > 0 ) dir[u] = up; if ( dpDown[u] > 0 ) dir[u] = down; //printf( "%d %d %d\n", u, dpDown[u], dpUp[u] ); } int main() { int n, m; cin >> n >> m; for ( int i = 0; i < m; i++ ) { int u, v; cin >> u >> v; edges[i] = { u, v }; if ( u == v ) continue; adj[u].push_back( v ); adj[v].push_back( u ); if ( u > v ) swap( u, v ); frecvEdges[u][v]++; } for ( int v = 1; v <= n; v++ ) { if ( !vis[v] ) findBiconexe( v, 0 ); } /*int i = 0; for ( vector<int> b: biconexe ) { for ( int v: b ) cout << v << " "; cout << "\n"; cout << countEdges[i++] << "\n"; } for ( int v: articulation ) cout << v << " "; cout << "\n";*/ int vert = 0; for ( int v: articulation ) { vertexArt[v] = ++vert; art[vert] = v; } for ( int i = 0; i < biconexe.size(); i++ ) { vertexBic[i] = ++vert; for ( int v: biconexe[i] ) { if ( vertexArt[v] ) { arbAdj[vertexArt[v]].push_back( vertexBic[i] ); arbAdj[vertexBic[i]].push_back( vertexArt[v] ); //printf( "edgearb %d %d %d %d\n", v, i, vertexArt[v], vertexBic[i] ); } else biconex[v] = i; } } for ( int v = 1; v <= n; v++ ) vis[v] = false; for ( int v = 1; v <= n; v++ ) { if ( !vis[v] ) dfs( v, 0 ); } initLca( vert ); for ( int v = 1; v <= vert; v++ ) dir[v] = none; int k; cin >> k; for ( int i = 0; i < k; i++ ) { int u, v; cin >> u >> v; int a = u, b = v; u = (vertexArt[u] ? vertexArt[u] : vertexBic[biconex[u]]); v = (vertexArt[v] ? vertexArt[v] : vertexBic[biconex[v]]); int l = lca( u, v ); //printf( "%d %d %d\n", u, v, l ); //printf( "%d %d\n", u, v ); if ( u == v && countEdges[u - 1 - articulation.size()] == 1 ) direction[a][b] = 1; if ( k <= 100 ) { while ( depthArb[u] > depthArb[v] ) { if ( u > articulation.size() ) dir[u] = up; //printf( "%d\n", u ); u = parent[0][u]; } while ( depthArb[v] > depthArb[u] ) { if ( v > articulation.size() ) dir[v] = down; // printf( "%d\n", v ); v = parent[0][v]; } while ( u != v ) { //printf( "%d\n%d\n", u, v ); if ( u > articulation.size()) dir[u] = up; u = parent[0][u]; if ( v > articulation.size()) dir[v] = down; v = parent[0][v]; } } else { updateUp[u]++; updateUp[parent[0][l]]--; updateDown[v]++; updateDown[parent[0][l]]--; } } for ( int v = 1; v <= n; v++ ) vis[v] = false; for ( int v = 1; v <= n; v++ ) { if ( !vis[v] ) calcUpDown( v, 0 ); } for ( int i = 0; i < biconexe.size(); i++ ) { int v = vertexBic[i]; if ( countEdges[i] != 1 ) continue; int a = biconexe[i][0], b = biconexe[i][1]; //printf( "ba %d %d %d\n", v, a, b ); if ( a == art[parent[0][v]] ) swap( a, b ); if ( dir[v] == up ) direction[a][b] = 1; else if ( dir[v] == down ) direction[b][a] = 1; } string ans = ""; for ( int i = 0; i < m; i++ ) { int u = edges[i].u, v = edges[i].v; if ( direction[u][v] ) ans += 'R'; else if ( direction[v][u] ) ans += 'L'; else ans += 'B'; //cout << i << " " << ans.back() << "\n"; } cout << ans; return 0; }

컴파일 시 표준 에러 (stderr) 메시지

oneway.cpp: In function 'int main()':
oneway.cpp:183:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  183 |     for ( int i = 0; i < biconexe.size(); i++ ) {
      |                      ~~^~~~~~~~~~~~~~~~~
oneway.cpp:224:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  224 |                 if ( u > articulation.size() )
      |                      ~~^~~~~~~~~~~~~~~~~~~~~
oneway.cpp:230:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  230 |                 if ( v > articulation.size() )
      |                      ~~^~~~~~~~~~~~~~~~~~~~~
oneway.cpp:237:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  237 |                 if ( u > articulation.size())
      |                      ~~^~~~~~~~~~~~~~~~~~~~~
oneway.cpp:240:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  240 |                 if ( v > articulation.size())
      |                      ~~^~~~~~~~~~~~~~~~~~~~~
oneway.cpp:259:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::vector<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  259 |     for ( int i = 0; i < biconexe.size(); i++ ) {
      |                      ~~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...