最大流

參見https://blog.csdn.net/lzoi_hmh/article/details/74940366

package graphModel;

import java.util.LinkedList;

class Edge {
    Edge() {
    }

    int next;
    int to;
    int w;

}

public class MaxFlow {
    public static int inf = 1000;//用於申請大數組,防止越界,同時也表示兩點之間不連接
    public static Edge[] edges = new Edge[inf];//存儲邊的數組
    public static int[] head = new int[inf];//鏈式前向星存儲圖結構
    public static int N = 6;//圖的節點個數
    public static int[] level = new int[N];//節點所在的層數
    public static int S = 0;//源節點
    public static int T = N - 1;//目的節點
    public static int cnt = 0;//用於鏈式前向星存儲圖結構

    public static void main(String[] args) {
        for (int i = 0; i < head.length; i++)
            head[i] = -1;
        int[][] dag = { { 0, 2, inf, 2, inf, inf }, { inf, 0, 2, inf, 2, inf }, { inf, inf, 0, inf, inf, 2 },
                { inf, inf, inf, 0, 2, inf }, { inf, inf, inf, inf, 0, 2 }, { inf, inf, inf, inf, inf, 0 } };
        init(dag);
        int ans = 0;
        while (bfs()) {
            ans += dfs(S, inf);
        }
        //根據殘餘圖輸出路徑
        for(int i=1;edges[i]!=null;i=i+2) {
            System.out.println(edges[i-1].to+"->"+edges[i].to+" "+edges[i].w);
        }
    }

    public static void init(int[][] dag) {
        for (int i = 0; i < dag.length; i++) {
            for (int j = dag.length - 1; j >= 0; j--) {
                if (dag[i][j] > 0 && dag[i][j] < inf) {
                    addEdge(i, j, dag[i][j]);
                    addEdge(j, i, 0);
                }

            }
        }
    }

    public static void addEdge(int u, int v, int w) {
        edges[cnt]=new Edge();
        edges[cnt].w = w;
        edges[cnt].to = v;
        edges[cnt].next = head[u];
        head[u] = cnt;
        cnt++;
    }

    public static int dfs(int u, int exp) {
        if (u == T)
            return exp;
        int flow = 0, tmp = 0;
        for (int i = head[u]; i != -1; i = edges[i].next) {
            int toU = edges[i].to;
            if ((level[toU] == (level[u] + 1)) && (edges[i].w > 0)) {
                tmp = dfs(toU, Math.min(exp, edges[i].w));
                if (tmp <= 0)
                    continue;

                exp -= tmp;
                flow += tmp;

                edges[i].w -= tmp;
//位運算符 ^ :1^1=0  0^1=1  2^1=3  3^1=2.
//建邊的時候,爲了方便 ^ 運算符使用,我們可以提前建好反向邊,之後一條邊,^ 一下就是另一條邊了
                edges[i ^ 1].w += tmp;
                if (exp <= 0)
                    break;
            }
        }
        return flow;
    }

    public static boolean bfs() {
        // 初始化level數組
        for (int i = 0; i < N; i++)
            level[i] = -1;
        LinkedList<Integer> queue = new LinkedList<Integer>();
        level[S] = 0;
        queue.add(S);
        while (!queue.isEmpty()) {
            int tmp = queue.poll();
            for (int i = head[tmp]; i != -1; i = edges[i].next) {
                int toTmp = edges[i].to;
                if (level[toTmp] == -1 && edges[i].w != 0) {
                    level[toTmp] = level[tmp] + 1;
                    queue.add(toTmp);
                }
            }
        }
        return level[T] != -1;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章