디닉 알고리즘 ( Java )

김현준·2023년 6월 5일
0

알고리즘

목록 보기
13/17

DinicMaxflowreturn flow 하면 최대유량 구할수있음.
Graph 클래스에 size 는 없어도 됨.

class Edge {
    public int v;
    public int flow;
    public int C;
    public int rev;

    public Edge(int v, int flow, int C, int rev) {
        this.v = v;
        this.flow = flow;
        this.C = C;
        this.rev = rev;
    }
}

class Graph {
    private int V;
    private int[] level;
    private List<Edge>[] adj;
    private int size; // 없어도됨.

    public Graph(int V , int size) {
        adj = new ArrayList[V];
        for (int i = 0; i < V; i++) {
            adj[i] = new ArrayList<Edge>();
        }
        this.V = V;
        this.size = size;
        level = new int[V];
    }

    public void addEdge(int u, int v, int C) {
        Edge a = new Edge(v, 0, C, adj[v].size());
        Edge b = new Edge(u, 0, 0, adj[u].size());

        adj[u].add(a);
        adj[v].add(b);
    }

    public boolean BFS(int s, int t) {
        for (int i = 0; i < V; i++) {
            level[i] = -1;
        }

        level[s] = 0;
        LinkedList<Integer> q = new LinkedList<Integer>();
        q.add(s);

        ListIterator<Edge> i;
        while (q.size() != 0) {
            int u = q.poll();

            for (i = adj[u].listIterator(); i.hasNext();) {
                Edge e = i.next();
                if (level[e.v] < 0 && e.flow < e.C) {
                    level[e.v] = level[u] + 1;
                    q.add(e.v);
                }
            }
        }

        return level[t] >= 0;
    }

    public int sendFlow(int u, int flow, int t, int start[]) {

        if (u == t) {
            return flow;
        }

        for (; start[u] < adj[u].size(); start[u]++) {

            Edge e = adj[u].get(start[u]);

            if (level[e.v] == level[u] + 1 && e.flow < e.C) {
                int curr_flow = Math.min(flow, e.C - e.flow);
                int temp_flow = sendFlow(e.v, curr_flow, t, start);

                if (temp_flow > 0) {
                    e.flow += temp_flow;
                    adj[e.v].get(e.rev).flow -= temp_flow;
                    return temp_flow;
                }
            }
        }

        return 0;
    }

    public void DinicMaxflow(int s, int t) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        if (s == t) {
            return;
        }
        int total = 0;
        while (BFS(s, t)) {
            int[] start = new int[V + 1];
            while (true) {
                int flow = sendFlow(s, Integer.MAX_VALUE, t, start);
                if (flow == 0) {
                    break;
                }
                total += flow;
            }
        }

        bw.write(Integer.toString(total));
        ArrayList<Integer> A = new ArrayList<>();
        ArrayList<Integer> B = new ArrayList<>();
        bw.newLine();
        for (int i = 1 ; i <= size; i++) {
            if (level[i]>0) {
                A.add(i);
            } else {
                B.add(i);
            }
        }

        for (Integer integer : A) {
            bw.write(Integer.toString(integer)+" ");
        }
        bw.newLine();
        for (Integer integer : B) {
            bw.write(Integer.toString(integer)+" ");
        }
        bw.newLine();
        bw.flush();
    }
}
profile
울산대학교 IT융합학부 22학번

0개의 댓글