이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |