Madiyar

acm.mipt.ru 098s2

Feb 14th, 2012
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.52 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstdlib>
  5. #include <vector>
  6. #include <set>
  7. #include <map>
  8. #include <cassert>
  9. #include <ctime>
  10. #include <cmath>
  11. #include <string>
  12. #include <cstring>
  13. #include <queue>
  14.  
  15. using namespace std;
  16.  
  17. #define f first
  18. #define s second
  19. #define mp make_pair
  20. #define pb push_back
  21. #define forit(it,v) for (typeof(v.begin()) it = v.begin(); it != v.end(); ++it)
  22. #define pii pair<int,int>
  23. const int maxm = 200001;
  24. const int maxn = 20001;
  25. vector<int> g[maxn], gi[maxn], order, g2[maxn];
  26. int comp[maxn], used[maxn], L[maxm], R[maxm], ver[maxn], in[maxn], out[maxn], cc, n, m, sl[maxn+10], timer;
  27. int tin[maxn], tout[maxn];
  28. vector<pii> ans;
  29.  
  30.  
  31. void Dfs1(int v) {
  32.  
  33.     comp[v] = true;
  34.  
  35.     forit(it, g[v]) {
  36.         int to = *it;
  37.         if (!comp[to]) Dfs1(to);
  38.     }
  39.  
  40.     order.pb(v);
  41. }
  42.  
  43. void Dfs2(int v) {
  44.    
  45.     comp[v] = cc;
  46.     ver[cc] = v;
  47.  
  48.     forit(it, gi[v]) {
  49.         int to = *it;
  50.         if (!comp[to]) Dfs2(to);
  51.     }
  52. }
  53.  
  54. void Dfs3(int v) {
  55.    
  56.     tin[v] = ++timer;
  57.     used[v] = 1;
  58.  
  59.     forit(it, g2[v]) {
  60.         int to = *it;
  61.    
  62.         if (!used[to]) Dfs3(to);       
  63.         else {
  64.             sl[tin[to]] = -1;
  65.             sl[tout[to]] = -2;
  66.         }
  67.     }
  68.  
  69.     tout[v] = ++timer;
  70. }
  71.  
  72. int main() {
  73.     scanf("%d%d", &n, &m);
  74.    
  75.     for (int i = 0; i < m; ++i) {
  76.         int u, v;
  77.         scanf("%d%d", &u, &v);     
  78.         g[u].pb(v);
  79.         gi[v].pb(u);
  80.         L[i] = u; R[i] = v;
  81.     }
  82.  
  83.     for (int i = 0; i < n; ++i)
  84.         if (!comp[i]) Dfs1(i);
  85.  
  86.     memset(comp, 0, sizeof(comp));
  87.     for (int i = (int)order.size() - 1; i >= 0; --i)
  88.         if (!comp[order[i]]) {
  89.             cc++;
  90.             Dfs2(order[i]);
  91.         }
  92.  
  93.     if (cc == 1) {
  94.         puts("0");
  95.         return 0;
  96.     }
  97.    
  98.     for (int i = 0; i < m; ++i) {
  99.         int u = L[i], v = R[i];
  100.  
  101.         if (comp[u] != comp[v]) {
  102.             g2[comp[u]].pb(comp[v]);
  103.             in[comp[v]] = true;
  104.             out[comp[u]] = true;
  105.         }
  106.     }
  107.  
  108.  
  109.     vector<int>  S, T;
  110.  
  111.     for (int i = 1; i <= cc; ++i) {
  112.         if (!in[i]) S.pb(i);
  113.         if (!out[i]) T.pb(i);
  114.     }
  115.  
  116.     int anscnt = max(S.size(), T.size());
  117.  
  118. //  cerr <<" ans = " << anscnt << endl;
  119.        
  120.     memset(used, 0, sizeof(used));
  121.  
  122.     forit (it1, S) {       
  123.        
  124.         int s = *it1;
  125.  
  126.         memset(sl, 0, sizeof(sl));
  127.        
  128.         Dfs3(s);
  129.  
  130.         forit(it2, T) {
  131.             int t = *it2;
  132.             if (!out[t] && !used[t]) {
  133.  
  134.                 ans.pb(mp(ver[t], ver[s]));
  135.                 g2[t].pb(s);
  136.                 out[t] = true;
  137.                 in[s] = true;
  138.                 break;
  139.             }
  140.         }
  141.  
  142.         if (in[s]) continue;
  143.  
  144.         sl[tin[s]] = -1;
  145.         sl[tout[s]] = -2;
  146.  
  147.         forit (it, T) {
  148.             if (!sl[tin[*it]])
  149.                 sl[tin[*it]] = *it;
  150.         }
  151.  
  152.         int op = 0;
  153.         for (int j = 1; j <= timer; ++j) {
  154.            
  155.             if (sl[j] == -1) op++; else
  156.             if (sl[j] == -2) op--; else
  157.             if (sl[j] != 0 && op == 0) {
  158.                 ans.pb(mp(ver[sl[j]], ver[s]));
  159.                 g2[sl[j]].pb(s);
  160.                 in[s] = true;
  161.                 out[sl[j]] = true;             
  162.                 break;
  163.             }
  164.         }                  
  165.     }
  166. /*  puts("begin");
  167.     forit(it, ans) {
  168.         cout << it -> f << " "<<it -> s << endl;   
  169.     }
  170.     puts("end");
  171.      */
  172.     int i = 0, j = 0;
  173.     while (i < S.size() && j < T.size()) {
  174.  
  175.         while (i < S.size() && in[S[i]]) i++;
  176.         while (j < T.size() && out[T[j]]) j++;
  177.  
  178.         if (i < S.size() && j < T.size()) {
  179.             ans.pb(mp(ver[T[j]], ver[S[i]]));
  180.             in[S[i]] = true;
  181.             out[T[j]] = true;
  182.         }
  183.     }
  184.  
  185.     int v = -1;
  186.     if (T.empty()) v = 0; else
  187.     v = ver[T[0]];
  188.  
  189.  
  190.  
  191.     while (i < S.size()) {
  192.  
  193.         if (!in[S[i]]) ans.pb(mp(v, ver[S[i]]));
  194.         i++;
  195.     }
  196.  
  197.     if (S.empty()) v = 0; else
  198.     v = ver[S[0]];
  199.    
  200.     while (j < T.size()) {
  201.  
  202.         if (!out[T[j]]) ans.pb(mp(ver[T[j]], v));
  203.         ++j;
  204.     }
  205.  
  206.  
  207.     assert(ans.size() == anscnt);
  208.     printf("%d\n", ans.size());
  209.     forit(it, ans) {
  210.         printf("%d %d\n", it -> f, it -> s);
  211.     }
  212.        
  213.     return 0;  
  214. }
Advertisement
Add Comment
Please, Sign In to add comment