FordFulkerson.java
package cn.denghanxi.s604;
import edu.princeton.cs.algs4.Queue;
/**
* Ford-Fulkerson 最大流量算法
*/
public class FordFulkerson {
private boolean[] marked; //在剩余网络中,是否存在从s到v的路径
private FlowEdge[] edgeTo; //从s到v的最短路径上的最后一条边
private double value; //当前最大流
public FordFulkerson(FlowNetWork graph, int s, int t) {
while (hasAugmentingPath(graph, s, t)) {
double bottle = Double.POSITIVE_INFINITY;
for (int v = t; v != s; v = edgeTo[v].other(v))
bottle = Math.min(bottle, edgeTo[v].residualFlowTo(v));
for (int v = t; v != s; v = edgeTo[v].other(v))
edgeTo[v].addResidualFlowTo(v, bottle);
value += bottle;
}
}
public double value() {
return value;
}
public boolean inCut(int v) {
return marked[v];
}
// 检测是否还有增广路径
private boolean hasAugmentingPath(FlowNetWork graph, int s, int t) {
marked = new boolean[graph.v()];
edgeTo = new FlowEdge[graph.v()];
Queue<Integer> q = new Queue<>();
marked[s] = true;
q.enqueue(s);
while (!q.isEmpty()) {
int v = q.dequeue();
for (FlowEdge edge : graph.adj(v)) {
int w = edge.other(v);
if (edge.residualFlowTo(w) > 0 && !marked[w]) {
edgeTo[w] = edge;
marked[w] = true;
q.enqueue(w);
}
}
}
return marked[t];
}
}