Tarango

SCC to DAG

Sep 4th, 2015
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | None | 0 0
  1. //SCC TO DAG Convert:
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int vertex,edges;
  5.  
  6. int indegree[10005];
  7. int low[10005];
  8. int disc[10005];
  9. bool taken[10005];
  10.  
  11. vector<int> Graph[10005];
  12. vector<int> rev_Graph[10005];
  13. vector<int> scc_List,rev_List,temp_List;
  14. stack<int> st;
  15. map<int,int> in_SCC,in_Boss,in_Rev,out_Graph;
  16.  
  17. int Time = 0;
  18.  
  19. void convert_SCC_To_DAG(int boss){
  20.     rev_List.clear();
  21.     in_SCC.clear();
  22.     in_Boss.clear();
  23.     in_Rev.clear();
  24.     temp_List.clear();
  25.     int Size = (int)scc_List.size();
  26.     if(Size == 1) return;
  27.     for(int i = 0;i<Size;i++){
  28.         in_SCC[scc_List[i]] = boss;
  29.         if(scc_List[i] != boss) out_Graph[scc_List[i]] = 1;
  30.     }
  31.     //Add all the neighbors of SCC members to their boss;
  32.     for(int i = 0;i<Size;i++){
  33.         int u = scc_List[i];
  34.         for(int j = 0;j<(int)Graph[u].size();j++){
  35.             int vert = Graph[u][j];
  36.             if(in_Boss.count(vert) == 0 && in_SCC.count(vert) == 0){
  37.                 in_Boss[vert] = 1;
  38.                 temp_List.push_back(vert);
  39.             }
  40.         }
  41.     }
  42.     Graph[boss].clear();
  43.     for(int i = 0;i<(int)temp_List.size();i++){
  44.         Graph[boss].push_back(temp_List[i]);
  45.     }
  46.  
  47.     //Update the nodes who have edge to SCC members.
  48.     //Step 1: List the nodes who have edge to SCC members:
  49.     for(int i = 0;i<Size;i++){
  50.         int u = scc_List[i];
  51.         for(int j = 0;j<(int)rev_Graph[u].size();j++){
  52.             int v = rev_Graph[u][j];
  53.             if(in_Rev.count(v) == 0 && in_SCC.count(v) == 0){
  54.                 in_Rev[v] = 1;
  55.                 rev_List.push_back(v);
  56.             }
  57.         }
  58.     }
  59.  
  60.     //Step 2: Update their neighbors-remove all SCC members-add boss.
  61.     for(int i = 0;i<(int)rev_List.size();i++){
  62.         int u = rev_List[i];
  63.         temp_List.clear();
  64.         for(int j = 0;j<(int)Graph[u].size();j++){
  65.             int vert = Graph[u][j];
  66.             if(in_SCC.count(vert) == 0){
  67.                 temp_List.push_back(vert);
  68.             }
  69.         }
  70.         Graph[u].clear();
  71.         for(int c = 0;c<(int)temp_List.size();c++){
  72.             Graph[u].push_back(temp_List[c]);
  73.         }
  74.         Graph[u].push_back(boss);
  75.     }
  76. }
  77.  
  78. void run_Tarjan_SCC(int u) {
  79.     disc[u] = low[u] = ++Time;
  80.     taken[u] = true;
  81.     st.push(u);
  82.  
  83.     int Size = Graph[u].size();
  84.     for (int i = 0; i < Size; i++) {
  85.         int v = Graph[u][i];
  86.         if (disc[v] == -1) {
  87.             run_Tarjan_SCC(v);
  88.             low[u] = min(low[u], low[v]);
  89.         } else if (taken[v] == true) {
  90.             low[u] = min(low[u], disc[v]);
  91.         }
  92.     }
  93.     if (disc[u] == low[u]) {
  94.         scc_List.clear();
  95.         scc_List.push_back(u);
  96.         while (st.top() != u) {
  97.             int adj = st.top();
  98.             taken[adj] = false;
  99.             st.pop();
  100.             scc_List.push_back(adj);
  101.         }
  102.         int adj = st.top();
  103.         taken[adj] = false;
  104.         st.pop();
  105.         convert_SCC_To_DAG(u);
  106.     }
  107. }
  108.  
  109. void find_SCC() {
  110.     memset(low, -1, sizeof(low));
  111.     memset(disc, -1, sizeof(disc));
  112.     memset(taken, false, sizeof(taken));
  113.     Time = -1;
  114.     for (int i = 0; i < vertex; i++) {
  115.         if (disc[i] == -1) {
  116.             run_Tarjan_SCC(i);
  117.         }
  118.     }
  119. }
  120.  
  121. int topological_sort(){
  122.     find_SCC();
  123.     int cnt = 0;
  124.     for(int u = 0;u<vertex;u++){
  125.         if(out_Graph.count(u)  == 1) continue;
  126.         for(int j = 0;j<(int)Graph[u].size();j++){
  127.             int v = Graph[u][j];
  128.             indegree[v]++;
  129.         }
  130.     }
  131.     for(int u = 0;u<vertex;u++){
  132.         if(out_Graph.count(u)  == 1) continue;
  133.         if(indegree[u] == 0) cnt++;
  134.     }
  135.     return cnt;
  136. }
  137.  
  138. void initialize() {
  139.     out_Graph.clear();
  140.     memset(indegree, 0, sizeof(indegree));
  141.     for (int i = 0; i < vertex; i++) {
  142.         Graph[i].clear();
  143.         rev_Graph[i].clear();
  144.     }
  145. }
  146.  
  147. void print_Graph(){
  148.     for(int i = 0;i<vertex;i++){
  149.         if(out_Graph.count(i) == 1) continue;
  150.         printf("Neighbors of %d :",i);
  151.         int Size = (int)Graph[i].size();
  152.         for(int j = 0;j<Size;j++){
  153.             printf(" -> %d",Graph[i][j]);
  154.         }
  155.         printf("\n");
  156.     }
  157. }
  158.  
  159. int main() {
  160.     int nCase, u, v;
  161.     scanf("%d", &nCase);
  162.     for (int cs = 1; cs <= nCase; cs++) {
  163.         scanf("%d %d", &vertex, &edges);
  164.         initialize();
  165.         for (int i = 0; i < edges; i++) {
  166.             scanf("%d %d", &u, &v);
  167.             u--;v--;
  168.             if(u == v) continue;
  169.             Graph[u].push_back(v);
  170.             rev_Graph[v].push_back(u);
  171.         }
  172.         int res = topological_sort();
  173.         printf("Case %d: %d\n",cs,res);
  174.     }
  175. }
Advertisement
Add Comment
Please, Sign In to add comment