Dang_Quan_10_Tin

BỘ GHÉP TỐI ĐA

Jul 27th, 2022
947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.04 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. #include <queue>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. using ll = long long;
  10. using ld = long double;
  11.  
  12. constexpr int N = 3e4 + 5;
  13. constexpr int block = 180;
  14. struct Edge
  15. {
  16.     int u, v;
  17.     ll c;
  18.     Edge() {}
  19.     Edge(int u, int v, ll c)
  20.     {
  21.         this->u = u;
  22.         this->v = v;
  23.         this->c = c;
  24.     }
  25. };
  26.  
  27. struct Dinic
  28. {
  29.     const ll Inf = 1e17;
  30.     vector<vector<int>> adj;
  31.     vector<vector<int>::iterator> cur;
  32.     vector<Edge> s;
  33.     vector<int> h;
  34.     int sink, t;
  35.     int n;
  36.     Dinic(int n = 0)
  37.     {
  38.         this->n = n;
  39.         adj.resize(n + 1);
  40.         h.resize(n + 1);
  41.         cur.resize(n + 1);
  42.         s.reserve(n);
  43.     }
  44.     void AddEdge(int u, int v, ll c)
  45.     {
  46.         s.emplace_back(u, v, c);
  47.         adj[u].push_back(s.size() - 1);
  48.         s.emplace_back(v, u, 0);
  49.         adj[v].push_back(s.size() - 1);
  50.     }
  51.     bool BFS()
  52.     {
  53.         fill(h.begin(), h.end(), n + 2);
  54.         queue<int> pq;
  55.         h[t] = 0;
  56.         pq.emplace(t);
  57.         while (pq.size())
  58.         {
  59.             int c = pq.front();
  60.             pq.pop();
  61.             for (auto i : adj[c])
  62.                 if (h[s[i ^ 1].u] == n + 2 && s[i ^ 1].c != 0)
  63.                 {
  64.                     h[s[i ^ 1].u] = h[c] + 1;
  65.                     if (s[i ^ 1].u == sink)
  66.                         return true;
  67.                     pq.emplace(s[i ^ 1].u);
  68.                 }
  69.         }
  70.         return false;
  71.     }
  72.     ll DFS(int v, ll flowin)
  73.     {
  74.         if (v == t)
  75.             return flowin;
  76.         ll flowout = 0;
  77.         for (; cur[v] != adj[v].end(); ++cur[v])
  78.         {
  79.             int i = *cur[v];
  80.             if (h[s[i].v] + 1 != h[v] || s[i].c == 0)
  81.                 continue;
  82.             ll q = DFS(s[i].v, min(flowin, s[i].c));
  83.             flowout += q;
  84.             if (flowin != Inf)
  85.                 flowin -= q;
  86.             s[i].c -= q;
  87.             s[i ^ 1].c += q;
  88.             if (flowin == 0)
  89.                 break;
  90.         }
  91.         return flowout;
  92.     }
  93.     void BlockFlow(ll &flow)
  94.     {
  95.         for (int i = 1; i <= n; ++i)
  96.             cur[i] = adj[i].begin();
  97.         flow += DFS(sink, Inf);
  98.     }
  99.     ll MaxFlow(int s, int t)
  100.     {
  101.         this->sink = s;
  102.         this->t = t;
  103.         ll flow = 0;
  104.         while (BFS())
  105.             BlockFlow(flow);
  106.         return flow;
  107.     }
  108. };
  109.  
  110. int m, n, p, q, in[N], beg[N], en[N];
  111. int l[N], r[N], id[N];
  112. vector<int> x[block], y[block];
  113.  
  114. void Read()
  115. {
  116.     cin >> m >> n;
  117.  
  118.     for (int i = 1; i <= m; ++i)
  119.         cin >> l[i] >> r[i];
  120.  
  121.     p = m;
  122.     q = n;
  123. }
  124.  
  125. void Solve()
  126. {
  127.  
  128.     for (int i = 1; i <= q; ++i)
  129.     {
  130.         in[i] = i / block + 1;
  131.         if (!beg[in[i]])
  132.             beg[in[i]] = i;
  133.         en[in[i]] = i;
  134.     }
  135.  
  136.     int source = p + q + block + 1,
  137.         sink = p + q + block + 2;
  138.  
  139.     /*
  140.         X: 1, 2, ..., p
  141.         Y: p + 1, p + 2, ..., p + q
  142.         sqrt: p + q + 1, p + q + 2, ..., p + q + block
  143.         source: p + q + block + 1,
  144.         sink: p + q + block + 2
  145.     */
  146.  
  147.     /// ----- Add Edge -----
  148.     Dinic f(p + q + block + 5);
  149.  
  150.     /// source -> X
  151.  
  152.     for (int i = 1; i <= p; ++i)
  153.         f.AddEdge(source, i, 1);
  154.  
  155.     /// X->Y
  156.  
  157.     for (int i = 1; i <= p; ++i)
  158.         for (int j = 1; j <= in[q]; ++j)
  159.             if ((beg[j] <= l[i] && en[j] > l[i]) || (en[j] >= r[i] && beg[j] < r[i]))
  160.             {
  161.                 for (int t = beg[j]; t <= en[j]; ++t)
  162.                     if (t <= l[i] || t >= r[i])
  163.                         f.AddEdge(i, p + t, 1);
  164.             }
  165.             else if (beg[j] >= r[i] || en[j] <= l[i])
  166.                 f.AddEdge(i, p + q + j, 1);
  167.  
  168.     for (int i = 1; i <= q; ++i)
  169.         f.AddEdge(p + q + in[i], p + i, 1);
  170.  
  171.     /// Y -> sink
  172.  
  173.     for (int i = 1; i <= q; ++i)
  174.         f.AddEdge(p + i, sink, 1);
  175.  
  176.     /// ----- Print -----
  177.  
  178.     cout << f.MaxFlow(source, sink) << "\n";
  179.  
  180.     for (int i = 0; i < (int)f.s.size(); i += 2)
  181.         if (f.s[i].v > p + q) // sink or sqrt
  182.         {
  183.             if (f.s[i].v != p + q + block + 2) // Just sqrt
  184.                 for (int j = 0; j < f.s[i ^ 1].c; ++j)
  185.                     x[f.s[i].v - p - q].emplace_back(f.s[i].u);
  186.         }
  187.         else if (f.s[i].v > p) // Y
  188.         {
  189.             if (f.s[i].u <= p) // Cung nay la tu X->y
  190.             {
  191.                 for (int j = 0; j < f.s[i ^ 1].c; ++j)
  192.                     cout << f.s[i].u << " " << f.s[i].v - p << "\n";
  193.             }
  194.             else //  Cung nay la tu sqrt->Y
  195.             {
  196.                 for (int j = 0; j < f.s[i ^ 1].c; ++j)
  197.                     y[f.s[i].u - p - q].emplace_back(f.s[i].v - p);
  198.             }
  199.         }
  200.  
  201.     for (int i = 1; i <= in[q]; ++i) // Noi bat ki tu X->sqrt->Y
  202.         while (!x[i].empty())
  203.         {
  204.             cout << x[i].back() << " " << y[i].back() << "\n";
  205.             x[i].pop_back();
  206.             y[i].pop_back();
  207.         }
  208. }
  209.  
  210. int32_t main()
  211. {
  212.     ios::sync_with_stdio(0);
  213.     cin.tie(0);
  214.     cout.tie(0);
  215.  
  216.     Read();
  217.     Solve();
  218. }
Advertisement
Add Comment
Please, Sign In to add comment