Advertisement
vahook

CF/732/F - Tourist Reform

Apr 21st, 2020
492
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. #define MAXN    400000
  5. #define MAXM    400000
  6.  
  7. using namespace std;
  8.  
  9. struct el {
  10.     int a;
  11.     int b;
  12.     bool isbridge;
  13. };
  14.  
  15. el elek[MAXM+1];
  16. /* v_a és v_b közötti élek + hanyadik élnek felelnek meg az eredeti listában */
  17. vector<pair<int, int>> pontok[MAXN+1];
  18.  
  19. int N, M;
  20.  
  21. /* Tarjan algoritmushoz */
  22. int tim[MAXN+1];
  23. int low[MAXN+1];
  24. int cnt = 1;
  25.  
  26. /* Legnagyobb komponens egy pontja és mérete, a 0 kezdőérték nekünk megfelelő */
  27. int maxpoint;
  28. int maxsize;
  29.  
  30. /* Elvágó élek megjelölése + legnagyobb elvágott részgráf egy pontjának
  31.  * megkeresése Tarjan algoritmussal */
  32. int
  33. tarjan(int from, int current)
  34. {
  35.     tim[current] = cnt++;
  36.     low[current] = tim[current];
  37.  
  38.     /* Jegyezzük, hogy bejárásnál hány másik pont van még a komponensen belül.*/
  39.     int child = 1;
  40.  
  41.     for(const auto& c : pontok[current]){
  42.         int to = c.first;
  43.        
  44.         if(!tim[to]){
  45.             int rc = tarjan(current, to);
  46.             low[current] = min(low[current], low[to]);
  47.             if(low[to] == tim[to]){
  48.                 elek[c.second].isbridge = true;
  49.                 if(rc > maxsize){
  50.                     maxsize = rc;
  51.                     maxpoint = to;
  52.                 }
  53.             }else
  54.                 child += rc;
  55.         }else if (to != from){
  56.             low[current] = min(low[current], tim[to]);
  57.         }
  58.     }
  59.     return child;
  60. }
  61.  
  62. void
  63. bridges_from(int p)
  64. {
  65.     int rc = tarjan(p, p);
  66.     if(rc > maxsize){
  67.         maxsize = rc;
  68.         maxpoint = p;
  69.     }
  70. }
  71.  
  72. /* Irányított körök készítése + hídak jó irányba forgatása */
  73. void
  74. fix_dfs(int from)
  75. {
  76.     /* Az elérési időre már nincs szükségünk, ezért újrahasznosíthatjuk mint
  77.      * "járt-e" tömb. Mivel a Tarjan minden pontot bejárt, ezért itt az összes
  78.      * érték nemnulla kezdetben. */
  79.     tim[from] = 0;
  80.  
  81.     for(const auto& c : pontok[from]){
  82.         int to = c.first;
  83.         auto& ell = elek[c.second];
  84.  
  85.         if(tim[to]){
  86.             /* "Oda élek" bejárási iránnyal szembe forgatva */
  87.             fix_dfs(to);
  88.             ell.a = to;
  89.             ell.b = from;
  90.         }else{
  91.             /* Vissza élek az oda élekkel ellentétes irányba */
  92.             ell.a = from;
  93.             ell.b = to;
  94.         }
  95.     }
  96. }
  97.  
  98. int
  99. main()
  100. {
  101.     ios_base::sync_with_stdio(false);
  102.  
  103.     /* Beolvasás */
  104.     cin >> N >> M;
  105.     for(int i = 0; i < M; i++){
  106.         cin >> elek[i].a >> elek[i].b;
  107.         pontok[elek[i].a].push_back({elek[i].b, i});
  108.         pontok[elek[i].b].push_back({elek[i].a, i});
  109.     }
  110.  
  111.     /* Megoldás */
  112.     bridges_from(1);
  113.     fix_dfs(maxpoint);
  114.  
  115.     /* Kiíratás */
  116.     cout << maxsize << endl;
  117.     for(int i = 0; i < M; i++)
  118.         cout << elek[i].a << " " << elek[i].b << endl;
  119.  
  120.     return 0;
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement