nikolaj

A

May 1st, 2015
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.11 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cassert>
  3. #include <cmath>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <vector>
  7.  
  8.  
  9. #define eprintf(...) fprintf(stderr, __VA_ARGS__)
  10.  
  11. using namespace std;
  12.  
  13. namespace nk {
  14.     namespace mcmf {
  15.         using t_f = long double;
  16.         using t_w = long double;
  17.         const t_w INF = 1. / 0.;
  18.  
  19.         struct edge {
  20.             int s, t;
  21.             t_f c, f;
  22.             t_w w;
  23.             edge() {}
  24.             edge(int s, int t, t_f c, t_f f, t_w w): s(s), t(t), c(c), f(f), w(w) {}
  25.         };
  26.  
  27.         struct graph {
  28.             int n;
  29.             std::vector<std::vector<int>> adj;
  30.             std::vector<edge> edges;
  31.             graph(int n): n(n) {
  32.                 adj.resize(n);
  33.             }
  34.             void add_edge(int s, int t, t_f c, t_w w) {
  35.                 adj[s].push_back(edges.size());
  36.                 edges.push_back(edge(s, t, c, 0, w));
  37.                 adj[t].push_back(edges.size());
  38.                 edges.push_back(edge(t, s, 0, 0, -w));
  39.             }
  40.         };
  41.  
  42.         void sp_3(graph &g, int s, std::vector<t_w> &d, std::vector<t_w> &ph, std::vector<int> &p) {
  43.             std::queue<int> pq;
  44.             std::vector<bool> v(g.n, 0);
  45.             pq.push(s);
  46.             d[s] = 0;
  47.             v[s] = 1;
  48.             while (!pq.empty()) {
  49.                 s = pq.front();
  50.                 pq.pop();
  51.                 v[s] = 0;
  52.                 for (auto id : g.adj[s]) {
  53.                     const edge &e = g.edges[id];
  54.                     if (e.c - e.f > 0 && d[e.t] + ph[e.t] > d[e.s] + ph[e.s] + e.w) {
  55.                         d[e.t] = ph[e.s] + d[e.s] - ph[e.t] + e.w;
  56.                         if (!v[e.t]) pq.push(e.t);
  57.                         v[e.t] = 1;
  58.                         p[e.t] = id;
  59.                     }
  60.                 }
  61.             }
  62.         }
  63.  
  64.         void sp_1(graph &g, int s, std::vector<t_w> &d, std::vector<t_w> &ph, std::vector<int> &p) {
  65.             std::fill(p.begin(), p.end(), -1);
  66.             std::fill(d.begin(), d.end(), INF);
  67.             std::priority_queue<std::pair<t_w, int> > pq;
  68.             d[s] = 0;
  69.             pq.push(std::make_pair(-d[s], s));
  70.             while (!pq.empty()) {
  71.                 auto cur = pq.top();
  72.                 pq.pop();
  73.                 s = cur.second;
  74.                 if (d[s] != -cur.first) continue;
  75.                 for (auto id : g.adj[s]) {
  76.                     const edge &e = g.edges[id];
  77.                     if (e.c - e.f > 0 && d[e.t] + ph[e.t] > d[e.s] + ph[e.s] + e.w) {
  78.                         d[e.t] = d[e.s] + ph[e.s] - ph[e.t] + e.w;
  79.                         p[e.t] = id;
  80.                         pq.push(std::make_pair(-d[e.t], e.t));
  81.                     }
  82.                 }
  83.             }
  84.         }
  85.  
  86.         void sp_2(graph &g, int s, std::vector<t_w> &d, std::vector<t_w> &ph, std::vector<int> &p) {
  87.             std::fill(p.begin(), p.end(), -1);
  88.             std::fill(d.begin(), d.end(), INF);
  89.             std::vector<bool> v(g.n, false);
  90.             d[s] = 0;
  91.             while (1) {
  92.                 int ind = -1;
  93.                 for (int i = 0; i < g.n; ++i) {
  94.                     if (!v[i] && (ind == -1 || d[ind] > d[i])) ind = i;
  95.                 }
  96.                 if (ind == -1) break;
  97.                 s = ind;
  98.                 v[s] = true;
  99.                 for (auto id : g.adj[s]) {
  100.                     const edge &e = g.edges[id];
  101.                     if (e.c - e.f > 0 && d[e.t] + ph[e.t] > d[e.s] + ph[e.s] + e.w) {
  102.                         d[e.t] = d[e.s] + ph[e.s] + e.w - ph[e.t];
  103.                         p[e.t] = id;
  104.                     }
  105.                 }
  106.             }
  107.         }
  108.  
  109.         void mcmf(graph &g, int s, int t, t_f L, t_f &f, t_w &w) {
  110.             w = 0;
  111.             f = 0;
  112.             std::vector<t_w> ph(g.n, 0);
  113.             std::vector<int> p(g.n, -1);
  114.             std::vector<t_w> d(g.n, INF);
  115.             sp_3(g, s, d, ph, p);
  116.             while (1) {
  117.                 sp_2(g, s, d, ph, p);
  118.                 if (p[t] == -1) break;
  119.                 int v = t;
  120.                 t_f vf = L - f;
  121.                 while (p[v] != -1) {
  122.                     const edge &e = g.edges[p[v]];
  123.                     vf = std::min(vf, e.c - e.f);
  124.                     v = e.s;
  125.                 }
  126.                 assert(vf > 0);
  127.                 f += vf;
  128.                 v = t;
  129.                 while (p[v] != -1) {
  130.                     edge &e = g.edges[p[v]];
  131.                     edge &er = g.edges[p[v] ^ 1];
  132.                     w += e.w * vf;
  133.                     e.f += vf;
  134.                     er.f -= vf;
  135.                     v = e.s;
  136.                 }
  137.                 for (int i = 0; i < g.n; i++) ph[i] += d[i];
  138.                 if (f == L) break;
  139.             }
  140.         }
  141.  
  142.         void compose(graph &g, int s, int t, std::vector<int> &p) {
  143.             if (s == t) return;
  144.             for (auto id : g.adj[s]) {
  145.                 const edge &e = g.edges[id];
  146.                 if (e.f > 0) {
  147.                     p[e.t] = id;
  148.                     return compose(g, e.t, t, p);
  149.                 }
  150.             }
  151.         }
  152.     }
  153. }
  154. //end nk
  155.  
  156. int main() {
  157.     assert(freopen("mincost.in", "rt", stdin));
  158.     assert(freopen("mincost.out", "wt", stdout));
  159.     int n, m;
  160.     scanf("%d%d", &n, &m);
  161.     nk::mcmf::graph g(n);
  162.     for (int i = 0; i < m; i++) {
  163.         int s, t, c, w;
  164.         scanf("%d%d%d%d", &s, &t, &c, &w);
  165.         s--, t--;
  166.         g.add_edge(s, t, c, w);
  167.     }
  168.     long double flow = 0;
  169.     long double cost = 0;
  170.     nk::mcmf::mcmf(g, 0, n - 1, nk::mcmf::INF, flow, cost);
  171.     printf("%lld\n", (long long)cost);
  172. }
Advertisement
Add Comment
Please, Sign In to add comment