Tarango

Forwarding Main(SCC+DAG)

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