最大流 : FordFulkerson 算法

来源:互联网 发布:角落音乐 淘宝 编辑:程序博客网 时间:2024/05/04 18:38
import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.Queue;public class FordFulkerson {static final int M = 10000; // unreachable/** * 查找AugmentPath(增广路径) * <pre> * @param edges : G(V,E) * @param f : 当前的最大流 * @param s : 源点 * @param t : 汇点 * @return * </pre> */static int[] getAugmentPath(int[][] edges, int[][] f, int s, int t) {int vertex = edges.length;boolean[] visited = new boolean[vertex];int[] p = new int[vertex];for (int i = 0; i < vertex; i++) {p[i] = -1;}visited[s] = true;Queue<Integer> queue = new LinkedList<Integer>();queue.add(s);boolean exist = false;while (!queue.isEmpty() && !exist) {int i = queue.poll();for (int j = 0; j < vertex; j++) {int remain = edges[i][j] - f[i][j];if (i != j && edges[i][j] < M && !visited[j] && remain > 0) {visited[j] = true;queue.offer(j);p[j] = i;if (j == t) {exist = true;break;}}}visited[i] = true;}if (!exist)return null;List<Integer> path = new ArrayList<Integer>();path.add(t);while (p[t] != -1) {path.add(0, p[t]);t = p[t];}int[] result = new int[path.size()];for (int i = 0; i < path.size(); i++) {result[i] = path.get(i);}return result;}/** * 获得增广路径上的最小残留值 * @param edges * @param f * @param augmentingPath * @return */static int getMinRemain(int[][] edges, int[][] f, int[] augmentingPath) {int remain = Integer.MAX_VALUE;for (int i = 0; i < augmentingPath.length - 1; i++) {int u = augmentingPath[i];int v = augmentingPath[i + 1];if (remain > (edges[u][v] - f[u][v]))remain = edges[u][v] - f[u][v];}return remain;}static void fordFulkerson(String[] vertexs, int[][] edges, int s, int t) {int vertex = vertexs.length;int[][] f = new int[vertex][vertex];int[] path = null;while ((path = getAugmentPath(edges, f, s, t)) != null) {int minRemain = getMinRemain(edges, f, path);for (int i = 0; i < path.length - 1; i++) {int u = path[i];int v = path[i + 1];f[u][v] = f[u][v] + minRemain;if(f[u][v] > edges[u][v]) {int delta = Math.min(f[u][v], f[v][u]);f[u][v] -= delta;f[v][u] -= delta;}}}System.out.println("Max Flow : ");for(int i = 0; i < vertex; i++) {for(int j = 0; j < vertex; j++) {if(f[i][j] <= 0)continue;System.out.printf("%s -> %s : %d\n", vertexs[i], vertexs[j], f[i][j]);}}}public static void main(String[] args) {// vertex nameString[] vertexs = { "s", "v1", "v2", "v3", "v4", "t" };// capacityint[][] edges = { { 0, 16, 13, M, M, M }, { M, 0, 10, 12, M, M }, { M, 4, 0, M, 14, M }, { M, M, 9, 0, M, 20 },{ M, M, M, 7, 0, 4 }, { M, M, M, M, M, 0 } };// source indexint s = 0;// sink indexint t = 5;fordFulkerson(vertexs, edges, s, t);}}

原创粉丝点击