Saturday, February 9, 2019

[Gym] 100513L - Useful Roads

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 100513L - Useful Roads
Source           : CodeChef
Category         : Graph Theory
Algorithm        : Dominator Tree
Verdict          : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. #define vi        vector <int>  
  6. #define eb        emplace_back  
  7. #define sz(v)     (int)v.size()  
  8. #define ll        long long int  
  9.   
  10. static const int maxn = 3e5 + 5;  
  11.   
  12. struct Node  
  13. {  
  14.       int v, e;  
  15.       Node(int v = 0, int e = 0) : v(v), e(e) {}  
  16. };  
  17.   
  18. vector <Node> graph[maxn], rgraph[maxn];  
  19. vector <int> Tree[maxn], bucket[maxn];  
  20.   
  21. int arr[maxn], par[maxn], rev[maxn], sdom[maxn], dom[maxn],  
  22.     dsu[maxn], label[maxn], dfsTime;  
  23.   
  24. int Find(int u, int x = 0)  
  25. {  
  26.       if (u == dsu[u]) return x ? -1 : u;  
  27.       int v = Find(dsu[u], x+1);  
  28.       if (v < 0) return u;  
  29.       if (sdom[ label[ dsu[u] ] ] < sdom[ label[u] ])  
  30.       {  
  31.             label[u] = label[ dsu[u] ];  
  32.       }  
  33.       dsu[u] = v;  
  34.       return x ? v : label[u];  
  35. }  
  36.   
  37. void Union(int u, int v)  
  38. {  
  39.       dsu[v] = u;  
  40. }  
  41.   
  42. void dfs(int u)  
  43. {  
  44.       ++dfsTime;  
  45.       arr[u] = dfsTime;  
  46.       rev[dfsTime] = u;  
  47.       label[dfsTime] = dfsTime;  
  48.       sdom[dfsTime] = dfsTime;  
  49.       dsu[dfsTime] = dfsTime;  
  50.       for (Node g : graph[u])  
  51.       {  
  52.             int v = g.v;  
  53.             if (!arr[v])  
  54.             {  
  55.                   dfs(v);  
  56.                   par[ arr[v] ] = arr[u];  
  57.             }  
  58.             rgraph[ arr[v] ].eb(arr[u]);  
  59.       }  
  60. }  
  61.   
  62. void DominatorTree(int src)  
  63. {  
  64.       dfs(src);  
  65.       int n = dfsTime;  
  66.       for (int i = n; i >= 1; i--)  
  67.       {  
  68.             for (int j = 0; j < sz(rgraph[i]); j++)  
  69.             {  
  70.                   sdom[i] = min(sdom[i], sdom[ Find(rgraph[i][j].v) ]);  
  71.             }  
  72.             if (i > 1) bucket[ sdom[i] ].eb(i);  
  73.             for (int j = 0; j < sz(bucket[i]); j++)  
  74.             {  
  75.                   int w = bucket[i][j];  
  76.                   int v = Find(w);  
  77.                   if (sdom[v] == sdom[w]) dom[w] = sdom[w];  
  78.                   else dom[w] = v;  
  79.             }  
  80.             if (i > 1) Union(par[i], i);  
  81.       }  
  82.       for (int i = 2; i <= n; i++)  
  83.       {  
  84.             if (dom[i] != sdom[i]) dom[i] = dom[ dom[i] ];  
  85.             Tree[ rev[i] ].eb(rev[ dom[i] ]);  
  86.             Tree[ rev[ dom[i] ] ].eb(rev[i]);  
  87.       }  
  88. }  
  89.   
  90. int in[maxn], out[maxn], ptr;  
  91.   
  92. void dfs1(int u, int p = -1)  
  93. {  
  94.       in[u] = ++ptr;  
  95.       for (int v : Tree[u])  
  96.       {  
  97.             if (v == p) continue;  
  98.             dfs1(v, u);  
  99.       }  
  100.       out[u] = ++ptr;  
  101. }  
  102.   
  103. int main()  
  104. {  
  105.       //freopen("in.txt", "r", stdin);  
  106.   
  107.       int tnode, tedge;  
  108.       while (cin >> tnode >> tedge)  
  109.       {  
  110.             for (int e = 1; e <= tedge; e++)  
  111.             {  
  112.                   int u, v;  
  113.                   cin >> u >> v;  
  114.                   graph[u].eb(v, e);  
  115.             }  
  116.             int src = 1;  
  117.             DominatorTree(src);  
  118.             dfs1(src);  
  119.             vector <int> useful;  
  120.             for (int u = 1; u <= tnode; u++)  
  121.             {  
  122.                   for (Node g : graph[u])  
  123.                   {  
  124.                         int v = g.v;  
  125.                         int e = g.e;  
  126.                         if (in[v] <= in[u] && out[v] >= out[u]) continue;  
  127.                         if (arr[u] == 0 || arr[v] == 0) continue;  
  128.                         useful.eb(e);  
  129.                   }  
  130.             }  
  131.             sort(useful.begin(), useful.end());  
  132.             int ans = sz(useful);  
  133.             cout << ans << endl;  
  134.             for (int r : useful) cout << r << " ";  
  135.             cout << endl;  
  136.   
  137.             dfsTime = 0;  
  138.             ptr = 0;  
  139.             useful.clear();  
  140.             for (int i = 1; i <= tnode; i++)  
  141.             {  
  142.                   graph[i].clear();  
  143.                   rgraph[i].clear();  
  144.                   Tree[i].clear();  
  145.                   bucket[i].clear();  
  146.                   arr[i] = 0;  
  147.                   rev[i] = 0;  
  148.                   par[i] = 0;  
  149.                   sdom[i] = 0;  
  150.                   dom[i] = 0;  
  151.                   label[i] = 0;  
  152.                   dsu[i] = 0;  
  153.                   in[i] = 0;  
  154.                   out[i] = 0;  
  155.             }  
  156.       }  
  157. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.