Advertisement
Alex_tz307

Eswaran-Tarjan Strong Connectivity Augmentation Problem

Apr 27th, 2021
653
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.58 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. void fastIO() {
  6.   ios_base::sync_with_stdio(false);
  7.   cin.tie(nullptr);
  8.   cout.tie(nullptr);
  9. }
  10.  
  11. const int MAXN = 1e5 + 1;
  12. const int MAXM = 2e5 + 1;
  13. vector<int> G[MAXN], GT[MAXN], D[MAXN], DT[MAXN];
  14. pair<int,int> edges[MAXM];
  15. bitset<MAXN> viz, is_source, is_sink;
  16. int vf, S[MAXN], ctc_cnt, node[MAXN], ctc_index[MAXN], sink;
  17. bool rev;
  18.  
  19. void dfs1(int u) {
  20.   viz[u] = true;
  21.   for (int v : G[u])
  22.     if (!viz[v])
  23.       dfs1(v);
  24.   S[++vf] = u;
  25. }
  26.  
  27. void dfs2(int u) {
  28.   ctc_index[u] = ctc_cnt;
  29.   for (int v : GT[u])
  30.     if (!ctc_index[v])
  31.       dfs2(v);
  32. }
  33.  
  34. void dfs(int u) {
  35.   viz[u] = true;
  36.   if (is_sink[u])
  37.     sink = u;
  38.   for (int v : D[u]) {
  39.     if (sink)
  40.       return;
  41.     if (!viz[v])
  42.       dfs(v);
  43.   }
  44. }
  45.  
  46. void print(int x, int y) {
  47.   if (rev)
  48.     cout << node[y] << ' ' << node[x] << '\n';
  49.   else cout << node[x] << ' ' << node[y] << '\n';
  50. }
  51.  
  52. void solve() {
  53.   int N, M;
  54.   cin >> N >> M;
  55.   for (int i = 0; i < M; ++i) {
  56.     int u, v;
  57.     cin >> u >> v;
  58.     if (u == v)
  59.       continue;
  60.     G[u].emplace_back(v);
  61.     GT[v].emplace_back(u);
  62.     edges[i] = make_pair(u, v);
  63.   }
  64.   for (int u = 1; u <= N; ++u)
  65.     if (!viz[u])
  66.       dfs1(u);
  67.   while (vf) {
  68.     int u = S[vf--];
  69.     if (!ctc_index[u]) {
  70.       node[++ctc_cnt] = u;
  71.       dfs2(u);
  72.     }
  73.   }
  74.   if (ctc_cnt == 1) {
  75.     cout << "0\n";
  76.     return;
  77.   }
  78.   for (int i = 0; i < M; ++i) {
  79.     int u, v;
  80.     tie(u, v) = edges[i];
  81.     u = ctc_index[u], v = ctc_index[v];
  82.     edges[i] = make_pair(u, v);
  83.     if (u != v) {
  84.       D[u].emplace_back(v);
  85.       DT[v].emplace_back(u);
  86.     }
  87.   }
  88.   vector<int> sources, sinks, isolated;
  89.   for (int u = 1; u <= ctc_cnt; ++u) {
  90.     if (D[u].empty() && DT[u].empty()) {
  91.       isolated.emplace_back(u);
  92.       continue;
  93.     }
  94.     if (D[u].empty())
  95.       sinks.emplace_back(u);
  96.     if (DT[u].empty())
  97.       sources.emplace_back(u);
  98.   }
  99.   if ((int)isolated.size() == ctc_cnt) {
  100.     cout << ctc_cnt << '\n';
  101.     for (int u = 1; u <= ctc_cnt; ++u) {
  102.       int v = u + 1;
  103.       if (v > ctc_cnt)
  104.         v = 1;
  105.       cout << node[u] << ' ' << node[v] << '\n';
  106.     }
  107.     return;
  108.   }
  109.   if (sinks.size() < sources.size()) {
  110.     rev = true;
  111.     swap(D, DT);
  112.     swap(sources, sinks);
  113.   }
  114.   for (int u : sources)
  115.     is_source[u] = true;
  116.   for (int u : sinks)
  117.     is_sink[u] = true;
  118.   vector<int> v{0}, w{0};
  119.   for (int u = 1; u <= ctc_cnt; ++u)
  120.     viz[u] = false;
  121.   for (int u : sources) {
  122.     sink = 0;
  123.     dfs(u);
  124.     if (sink) {
  125.       v.emplace_back(u);
  126.       w.emplace_back(sink);
  127.       is_source[u] = is_sink[sink] = false;
  128.     }
  129.   }
  130.   int s = sources.size(), t = sinks.size(), q = isolated.size(), p = v.size() - 1;
  131.   for (int u : sources)
  132.     if (is_source[u])
  133.       v.emplace_back(u);
  134.   for (int u : sinks)
  135.     if (is_sink[u])
  136.       w.emplace_back(u);
  137.   sources.insert(sources.begin(), 0);
  138.   sinks.insert(sinks.begin(), 0);
  139.   isolated.insert(isolated.begin(), 0);
  140.   cout << max(s, t) + q << '\n';
  141.   for (int i = 1; i < p; ++i)
  142.     print(w[i], v[i + 1]);
  143.   for (int i = p + 1; i <= s; ++i)
  144.     print(w[i], v[i]);
  145.   if (q == 0 && s == t) {
  146.     print(w[p], v[1]);
  147.   } else {
  148.     if (s < t) {
  149.       print(w[p], w[s + 1]);
  150.       for (int i = s + 1; i < t; ++i)
  151.         print(w[i], w[i + 1]);
  152.     }
  153.     if (q == 0 && s < t) {
  154.       print(w[t], v[1]);
  155.     } else {
  156.       print(w[t], isolated[1]);
  157.       for (int i = 1; i < q; ++i)
  158.         print(isolated[i], isolated[i + 1]);
  159.       print(isolated[q], v[1]);
  160.     }
  161.   }
  162. }
  163.  
  164. int main() {
  165.   fastIO();
  166.   solve();
  167.   return 0;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement