Advertisement
Lexolordan

Untitled

Nov 21st, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.12 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <set>
  4. #include <algorithm>
  5.  
  6. using namespace std;
  7.  
  8. typedef long long ll;
  9.  
  10. const int MAXN = 300;
  11. int from = MAXN * 2, to = 2 * MAXN + 1;
  12. const int INF = 1e9;
  13.  
  14. vector<int> dist(2 * MAXN + 2, INF);
  15. vector<int> p(2 * MAXN + 2);
  16. vector<int> been(2 * MAXN + 2);
  17.  
  18. struct Edge {
  19.     int _from, _to, cost, flow, capacity;
  20.     Edge* back_edge;
  21.  
  22.     Edge(int from, int to, int capacity, int cost) : _from(from), _to(to), capacity(capacity), cost(cost), flow(0),
  23.                                                      back_edge(0) {}
  24.  
  25.     inline int getCost() const {
  26.         return cost + p[_from] - p[_to];
  27.     }
  28.  
  29.     inline int getCapacity() const {
  30.         return capacity - flow;
  31.     }
  32. };
  33.  
  34. vector<int> d[MAXN];
  35. vector<Edge*> g[5 * MAXN];
  36. vector<Edge*> edges;
  37. vector<Edge*> prevs(5 * MAXN, nullptr);
  38.  
  39. int main() {
  40.     cin.tie(0);
  41.     ios_base::sync_with_stdio(false);
  42.  
  43.     int n;
  44.     cin >> n;
  45.  
  46.     for (int i = 0; i < n; ++i) {
  47.         d[i].resize(n);
  48.         for (int j = 0; j < n; ++j) {
  49.             cin >> d[i][j];
  50.         }
  51.     }
  52.  
  53.     for (int i = 0; i < n; ++i) {
  54.         for (int j = 0; j < n; ++j) {
  55.             Edge *e = new Edge(i, MAXN + j, 1, d[i][j]);
  56.             Edge *back_edge = new Edge(MAXN + j, i, 0, -d[i][j]);
  57.  
  58.             e->back_edge = back_edge;
  59.             back_edge->back_edge = e;
  60.  
  61.             g[i].push_back(e);
  62.             g[MAXN + j].push_back(back_edge);
  63.  
  64.             edges.push_back(e);
  65.             edges.push_back(back_edge);
  66.         }
  67.     }
  68.  
  69.     for (int i = 0; i < 2 * MAXN + 2; ++i) {
  70.         random_shuffle(g[i].begin(), g[i].end());
  71.     }
  72.  
  73.     for (int i = 0; i < n; ++i) {
  74.         Edge *e = new Edge(from, i, 1, 0);
  75.         Edge *back_edge = new Edge(i, from, 0, 0);
  76.  
  77.         e->back_edge = back_edge;
  78.         back_edge->back_edge = e;
  79.  
  80.         g[from].push_back(e);
  81.         g[i].push_back(back_edge);
  82.  
  83.         edges.push_back(e);
  84.         edges.push_back(back_edge);
  85.     }
  86.  
  87.     for (int i = 0; i < n; ++i) {
  88.         Edge *e = new Edge(MAXN + i, to, 1, 0);
  89.         Edge *back_edge = new Edge(to, MAXN + i, 0, 0);
  90.  
  91.         e->back_edge = back_edge;
  92.         back_edge->back_edge = e;
  93.  
  94.         g[MAXN + i].push_back(e);
  95.         g[to].push_back(back_edge);
  96.  
  97.         edges.push_back(e);
  98.         edges.push_back(back_edge);
  99.     }
  100.  
  101.     dist.assign(2 * MAXN + 2, INF);
  102.     prevs.assign(2 * MAXN + 2, nullptr);
  103.  
  104.     dist[from] = 0;
  105.     for (int i = 0; i < 2 * MAXN + 2; ++i) {
  106.         for (auto x : edges) {
  107.             if (x->getCapacity() > 0 && dist[x->_from] != INF && dist[x->_to] > dist[x->_from] + x->cost) {
  108.                 dist[x->_to] = dist[x->_from] + x->cost;
  109.                 prevs[x->_to] = x;
  110.             }
  111.         }
  112.     }
  113.  
  114.     for (int i = 0; i < 2 * MAXN + 2; ++i) {
  115.         p[i] = dist[i];
  116.     }
  117.  
  118.     int ans = 0;
  119.     while (dist[to] != INF) {
  120.         int now = to;
  121.         while (prevs[now] != nullptr) {
  122.             prevs[now]->flow++;
  123.             prevs[now]->back_edge->flow--;
  124.             ans += prevs[now]->cost;
  125.  
  126.             now = prevs[now]->_from;
  127.         }
  128.  
  129.         dist.assign(2 * MAXN + 2, INF);
  130.         prevs.assign(2 * MAXN + 2, nullptr);
  131.         been.assign(2 * MAXN + 2, 0);
  132.  
  133.         dist[from] = 0;
  134.         for (int i = 0; i < 2 * MAXN + 2; ++i) {
  135.             int v = -1;
  136.             for (int j = 0; j < 2 * MAXN + 2; ++j)
  137.                 if (!been[j] && (v == -1 || dist[j] < dist[v]))
  138.                     v = j;
  139.  
  140.             if (dist[v] == INF)
  141.                 break;
  142.             been[v] = true;
  143.  
  144.             for (auto e : g[v]) {
  145.                 if (e->getCapacity() > 0 && dist[v] + e->getCost() < dist[e->_to]) {
  146.                     dist[e->_to] = dist[v] + e->getCost();
  147.                     prevs[e->_to] = e;
  148.                 }
  149.             }
  150.         }
  151.  
  152.         for (int i = 0; i < 2 * MAXN + 2; ++i) {
  153.             p[i] = p[i] + dist[i];
  154.         }
  155.     }
  156.  
  157.     cout << ans << '\n';
  158.     for (auto x : edges) {
  159.         if (x->_from < MAXN && x->flow > 0) {
  160.             cout << x->_from + 1 << " " << x->_to - MAXN + 1 << '\n';
  161.         }
  162.     }
  163.  
  164.     return 0;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement