Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define all(x) (x).begin(), (x).end()
- #define TRACE(x) x
- #define WATCH(x) TRACE(cout << #x" = " << x << endl)
- #define PRINT(x...) TRACE(printf(x))
- #define WATCHR(a, b) TRACE(for (auto c=a; c!=b;) cout << *(c++) << " "; cout << endl)
- #define WATCHC(V) TRACE({cout << #V" = "; WATCHR(V.begin(), V.end());})
- #define FU(i, a, b) for (auto i = a; i < b; ++i)
- #define fu(i, b) FU(i, 0, b)
- #define FD(i, a, b) for (auto i = (b) - 1; i >= a; --i)
- #define fd(i, b) FD(i, 0, b)
- #define sz(x) (int) (x).size()
- #define pb push_back
- using ll = long long;
- using vi = vector<int>;
- using vvi = vector<vi>;
- using vll = vector<ll>;
- using vvll = vector<vll>;
- using vd = vector<double>;
- using vb = vector<bool>;
- using pii = pair<int, int>;
- using pll = pair<ll, ll>;
- ll mod(ll a, ll b) {
- return ((a%b)+b)%b;
- }
- int cmp(double x, double y = 0, double tol = 1.e-7) {
- return (x <= y + tol) ? (x + tol < y) ? -1 : 0 : 1;
- }
- struct graph {
- //////////////////////////////////////////////////////////////////////////////
- // Shared part. Also known as: You will need this!
- //
- vi dest; // use sz(dest) as nar
- vvi adj; // use sz(adj) as nvt
- int inv(int a) { return a ^ 0x1; }
- graph(int n = 0) {
- adj.resize(n);
- }
- // Adds an arc to the graph. u is capacity, c is cost.
- // u is only needed on flows, and c only on min-cost-flow
- int arc(int i, int j) {
- dest.pb(j);
- adj[i].pb(sz(dest)-1);
- dest.pb(i);
- adj[j].pb(sz(dest)-1);
- return sz(dest)-2;
- }
- //////////////////////////////////////////////////////////////////////////////
- // Both Bridges/Articulation points and to Strongly Connected Components
- //
- vi depth;
- //////////////////////////////////////////////////////////////////////////////
- // Strongly Connected Components - O(n+m)
- // see [rep] for results
- //
- vi ord, rep;
- int transp(int a) { return (a & 0x1); }
- void dfs_topsort(int u) {
- for (int a : adj[u]) {
- int v = dest[a];
- if (!transp(a) && depth[v] == -1) {
- depth[v] = depth[u] + 1;
- dfs_topsort(v);
- }
- }
- ord.pb(u);
- }
- void dfs_compfortcon(int u, int ent) {
- rep[u] = ent;
- for (int a : adj[u]) {
- int v = dest[a];
- if (transp(a) && rep[v] == -1) dfs_compfortcon(v, ent);
- }
- }
- void compfortcon() {
- depth = vi(sz(adj), -1);
- ord.clear();
- fu(u, sz(adj)) if (depth[u] == -1) {
- depth[u] = 0;
- dfs_topsort(u);
- }
- rep = vi(sz(adj), -1);
- for (int i = sz(adj)-1, j = 0; i >= 0; i--) if (rep[ord[i]] == -1)
- dfs_compfortcon(ord[i], j++);
- reverse( ord.begin(), ord.end() );
- }
- };
- int n, m;
- vector< pair<int, int> > edges;
- vector< vector<int> > secondGraph;
- vector<int> edgeColors;
- // Estou lidando com intervalos semi-abertos!!!
- void recursiveMark(int start, int end, int color, const graph& GRAPH) {
- vector<int> nodes;
- vector<int> groups(n, -1);
- int groupSize = (end - start) / 42 + 1;
- for(int i = start; i < end; ++i) {
- groups[ GRAPH.ord[i] ] = ( i - start ) / groupSize;
- }
- deque<bool> pendente( (end - start) / groupSize + 1, false);
- for(int i = start; i < end; ++i) {
- for(const auto& out : secondGraph[ GRAPH.ord[i] ] ) {
- int dest = edges[out].second;
- if( groups[dest] != groups[ GRAPH.ord[i] ] && edgeColors[out] == -1 && groups[ dest ] != -1) edgeColors[out] = color;
- else if( groups[ GRAPH.ord[i] ] == groups[dest] ) pendente[ groups[GRAPH.ord[i]] ] = true;
- }
- }
- for(int g = 0; g < (int) pendente.size(); ++g) {
- if( pendente[g] ) {
- int st = g * groupSize;
- int nd = st + groupSize;
- nd = min( nd, n );
- recursiveMark(st, nd, color + 1, GRAPH);
- }
- }
- }
- int main()
- {
- ios::sync_with_stdio( false );
- cin.tie(NULL);
- cin >> n >> m;
- edgeColors.assign(m, -1);
- graph g(n);
- secondGraph.resize(n);
- for(int i = 0; i < m; ++i) {
- int a, b;
- cin >> a >> b;
- --a; --b;
- g.arc(a, b);
- edges.emplace_back(a, b);
- secondGraph[a].push_back(i);
- }
- g.compfortcon();
- recursiveMark(0, n, 0, g);
- for(const int& c : edgeColors) {
- if( c == 0 ) cout << "R";
- else if( c == 1) cout << "G";
- else cout << "B";
- cout << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement