qwerty787788

MinCostMaxFlow

Dec 22nd, 2012
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.53 KB | None | 0 0
  1. class MinCostMaxFlowGraph {
  2.         int n;
  3.         ArrayList<Edge>[] g;
  4.  
  5.         class Edge {
  6.             int from, to;
  7.             long cap, flow, cost;
  8.             Edge rev;
  9.  
  10.             public Edge(int from, int to, long cap, long flow, long cost) {
  11.                 super();
  12.                 this.from = from;
  13.                 this.to = to;
  14.                 this.cap = cap;
  15.                 this.flow = flow;
  16.                 this.cost = cost;
  17.             }
  18.         }
  19.  
  20.         class Vertex implements Comparable<Vertex> {
  21.             int v;
  22.             Edge e;
  23.             long d;
  24.  
  25.             public Vertex(int v) {
  26.                 super();
  27.                 this.v = v;
  28.             }
  29.  
  30.             @Override
  31.             public int compareTo(Vertex o) {
  32.                 return d < o.d ? -1 : d > o.d ? 1 : v - o.v;
  33.             }
  34.  
  35.         }
  36.  
  37.         public MinCostMaxFlowGraph(int n) {
  38.             super();
  39.             this.n = n;
  40.             g = new ArrayList[n];
  41.             for (int i =0; i < n; i++)
  42.                 g[i] = new ArrayList<Edge>();
  43.         }
  44.  
  45.         public void addEdge(int fr, int to, int cap, long cost) {
  46.             Edge e1 = new Edge(fr, to, cap, 0, cost);
  47.             Edge e2 = new Edge(to, fr, 0, 0, -cost);
  48.             e1.rev = e2;
  49.             e2.rev = e1;
  50.             g[fr].add(e1);
  51.             g[to].add(e2);
  52.         }
  53.  
  54.         public long[] getMinCostMaxFlow(int source, int target) {
  55.             long[] h = new long[n];
  56.             for (boolean changed = true; changed; ) {
  57.                 changed = false;
  58.                 for (int i = 0; i < n; i++) {
  59.                     for (Edge e : g[i]) {
  60.                         if (e.cap > 0 && h[e.to] > h[e.from] + e.cost) {
  61.                             h[e.to] = h[e.from] + e.cost;
  62.                             changed = true;
  63.                         }
  64.                     }
  65.                 }
  66.             }
  67.             Vertex[] vertices = new Vertex[n];
  68.             long[] d = new long[n];
  69.             for (int i = 0; i < vertices.length; i++) {
  70.                 vertices[i] = new Vertex(i);
  71.             }
  72.             int flow = 0;
  73.             long cost = 0;
  74.             while (true) {
  75.                 dijkstra(source, vertices, d, h);
  76.                 if (d[target] == Long.MAX_VALUE) {
  77.                     break;
  78.                 }
  79.                 long addFlow = Long.MAX_VALUE;
  80.                 Vertex v = vertices[target];
  81.                 while (v != vertices[source]) {
  82.                     addFlow = Math.min(addFlow, v.e.cap - v.e.flow);
  83.                     v = vertices[v.e.from];
  84.                 }
  85.                 cost += (d[target] + h[target] - h[source]) * addFlow;
  86.                 flow += addFlow;
  87.                 v = vertices[target];
  88.                 while (v != vertices[source]) {
  89.                     v.e.flow += addFlow;
  90.                     v.e.rev.flow -= addFlow;
  91.                     v = vertices[v.e.from];
  92.                 }
  93.                 for (int i = 0; i < n; i++) {
  94.                     h[i] += d[i] == Long.MAX_VALUE ? 0 : d[i];
  95.                 }
  96.             }
  97.             return new long[]{flow, cost};
  98.         }
  99.  
  100.         void dijkstra(int source, Vertex[] vertices, long[] d, long[] h) {
  101.             TreeSet<Vertex> ts = new TreeSet<Vertex>();
  102.             Arrays.fill(d, Long.MAX_VALUE);
  103.             for (int i = 0; i < vertices.length; i++) {
  104.                 vertices[i].d = Long.MAX_VALUE;
  105.             }
  106.             d[source] = 0;
  107.             vertices[source].d = 0;
  108.             ts.add(vertices[source]);
  109.             while (!ts.isEmpty()) {
  110.                 Vertex v = ts.pollFirst();
  111.                 for (Edge e : g[v.v]) {
  112.                     if (e.flow >= e.cap) {
  113.                         continue;
  114.                     }
  115.                     if (d[e.to] == Long.MAX_VALUE
  116.                             || d[e.to] > d[e.from] + e.cost + h[e.from]
  117.                                     - h[e.to]) {
  118.                         if (e.cost + h[e.from] - h[e.to] < 0) {
  119.                             throw new AssertionError();
  120.                         }
  121.                         if (ts.contains(vertices[e.to])) {
  122.                             ts.remove(vertices[e.to]);
  123.                         }
  124.                         d[e.to] = d[e.from] + e.cost + h[e.from] - h[e.to];
  125.                         vertices[e.to].d = d[e.to];
  126.                         vertices[e.to].e = e;
  127.                         ts.add(vertices[e.to]);
  128.                     }
  129.                 }
  130.             }
  131.         }
  132.     }
Advertisement
Add Comment
Please, Sign In to add comment