Advertisement
K_Y_M_bl_C

Untitled

Dec 6th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.15 KB | None | 0 0
  1. #define _GLIBCXX_DEBUG
  2. //#define FAST_ALLOCATOR_MEMORY 5e7
  3. #ifdef _DEBUG
  4. #include "opt.h"
  5. #endif
  6. #include <bits/stdc++.h>
  7.  
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11. typedef pair<int, int> pii;
  12. typedef vector<int> vi;
  13.  
  14. #define mk make_pair
  15. #define inb push_back
  16. #define X first
  17. #define Y second
  18. #define all(v) v.begin(), v.end()
  19. #define sqr(x) (x) * (x)
  20.  
  21. int solve();
  22.  
  23. int main()
  24. {
  25.     //ios_base::sync_with_stdio(0);
  26.     //cin.tie(0);
  27. #define TASK "carno"
  28. #ifndef _DEBUG
  29.     //freopen(TASK".in", "r", stdin), freopen(TASK".out", "w", stdout);
  30. #endif
  31.     solve();
  32. }
  33.  
  34. const int INF = 2e9 + 7;
  35. const int N = 300;
  36. const int MAXN = 2 * N + 2;
  37.  
  38. struct edge
  39. {
  40.     int c, f, w, to;
  41.     edge() {};
  42.     edge(int c, int w, int to) : f(0), c(c), w(w), to(to) {};
  43. };
  44.  
  45. int solve()
  46. {
  47.     int n = readInt();
  48.     vector<edge> e;
  49.     int cnt = 2 * n + 2;
  50.     int g[MAXN][MAXN];
  51.     for (int i = 0; i < cnt; ++i)
  52.         memset(g[i], -1, sizeof g[i]);
  53.     //[0, n) - str
  54.     //[n, 2 * n) - col
  55.     //-> 2 * n
  56.     //<- 2 * n + 1
  57.     function<void(int, int, int, int)> addEdge = [&](int x, int y, int w, int c)
  58.     {
  59.         g[x][y] = e.size();
  60.         e.inb(edge(c, w, y));
  61.         g[y][x] = e.size();
  62.         e.inb(edge(0, -w, x));
  63.     };
  64.     int dst[cnt];
  65.     memset(dst, 0, sizeof dst);
  66.     vi phi(cnt);
  67.     for (int i = 0; i < n; ++i)
  68.     {
  69.         addEdge(2 * n, i, 0, 1);
  70.         addEdge(i + n, 2 * n + 1, 0, 1);
  71.         phi[i + n] = INF;
  72.     }
  73.     for (int i = 0; i < n; ++i)
  74.     {
  75.         for (int j = 0; j < n; ++j)
  76.         {
  77.             int w = readInt();
  78.             phi[j + n] = min(phi[j + n], w);
  79.             addEdge(i, j + n, w, 1);
  80.         }
  81.     }
  82.     int flow = 0;
  83.     int IT = 0;
  84.     int p[cnt];
  85.     int was[cnt];
  86.     memset(was, 0, sizeof was);
  87.     for (;;)
  88.     {
  89.         ++IT;
  90.         memset(p, -1, sizeof p);
  91.         for (int i = 0; i < cnt; ++i)
  92.         {
  93.             if (dst[i] == INF)
  94.                 continue;
  95.             phi[i] += dst[i];
  96.         }
  97.         fill(dst, dst + cnt, INF);
  98.         dst[2 * n] = 0;
  99.         for (int it = 0; it + 1 < cnt; ++it)
  100.         {
  101.             int u = -1;
  102.             for (int i = 0; i < cnt; ++i)
  103.             {
  104.                 if (was[i] == IT)
  105.                     continue;
  106.                 if (u == -1)
  107.                 {
  108.                     u = i;
  109.                 }
  110.                 else
  111.                 {
  112.                     if (dst[i] < dst[u])
  113.                         u = i;
  114.                 }
  115.             }
  116.             was[u] = IT;
  117.             for (int v = 0; v < cnt; ++v)
  118.             {
  119.                 if (g[u][v] == -1)
  120.                     continue;
  121.                 int &nedge = g[u][v];
  122.                 if (e[nedge].f >= e[nedge].c)
  123.                     continue;
  124.                 int to = e[nedge].to;
  125.                 if (dst[to] > dst[u] + e[nedge].w + phi[u] - phi[to])
  126.                 {
  127.                     dst[to] = dst[u] + e[nedge].w + phi[u] - phi[to];
  128.                     p[to] = nedge;
  129.                 }
  130.             }
  131.         }
  132.         if (dst[2 * n + 1] == INF)
  133.             break;
  134.         int minc = INF;
  135.         int u = 2 * n + 1;
  136.         vi eres;
  137.         while (p[u] != -1)
  138.         {
  139.             int nedge = p[u];
  140.             eres.inb(nedge);
  141.             minc = min(e[nedge].c - e[nedge].f, minc);
  142.             u = e[nedge ^ 1].to;
  143.         }
  144.         if (!minc)
  145.             break;
  146.         flow += minc;
  147.         for (auto x : eres)
  148.         {
  149.             e[x].f += minc;
  150.             e[x ^ 1].f -= minc;
  151.         }
  152.     }
  153.     ll sum = 0;
  154.     for (auto x : e)
  155.     {
  156.         sum += (x.f > 0) * (ll)x.w;
  157.     }
  158.     writeInt(sum, '\n');
  159.     for (int nedge = 0; nedge < e.size(); ++nedge)
  160.     {
  161.         if (e[nedge].f > 0 && e[nedge].to < 2 * n && e[nedge ^ 1].to < 2 * n)
  162.         {
  163.             writeInt(e[nedge ^ 1].to + 1, ' ');
  164.             writeInt(e[nedge].to - n + 1, '\n');
  165.             //printf("%d %d\n", e[nedge ^ 1].to + 1, e[nedge].to - n + 1);
  166.         }
  167.     }
  168.     return 0;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement