Tarango

Light OJ Light The Switches(SCC+DAG)

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