Cod sursa(job #2257832)

Utilizator kitkat007Graphy kitkat007 Data 10 octombrie 2018 15:56:38
Problema Flux maxim Scor 0
Compilator java Status done
Runda Arhiva educationala Marime 3.05 kb
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(new FileReader("maxflow.in"));
        PrintWriter pw = new PrintWriter("maxflow.out");
        int n = sc.nextInt();
        int m = sc.nextInt();
        UnorderedGraph graph = new UnorderedGraph(n);
        while (m-- > 0) {
            int from = sc.nextInt();
            int to = sc.nextInt();
            int capacity = sc.nextInt();
            graph.addEdge(from, to, capacity);
        }
        pw.print(graph.computeMaxFlow());
    }

    static class UnorderedGraph {
        private static final int INF = 110013 * 5000;
        int[][] capacity;
        int sourceNode;
        int destNode;
        int cntNodes;

        UnorderedGraph(int n) {
            cntNodes = n;
            sourceNode = 1;
            destNode = n;
            capacity = new int[n + 1][n + 1];
        }

        void addEdge(int from, int to, int c) {
            capacity[from][to] = c;
        }

        int computeMaxFlow() {
            int totalFlow = 0;
            List<Integer> augmentedPath = new ArrayList<>();
            while (getAugmentedPath(augmentedPath)) {
                int minFlow = INF;
                for (int i = 0; i < augmentedPath.size() - 1; ++i) {
                    int from = augmentedPath.get(i);
                    int to = augmentedPath.get(i + 1);
                    minFlow = Math.min(minFlow, capacity[from][to]);
                }
                for (int i = 0; i < augmentedPath.size() - 1; ++i) {
                    int from = augmentedPath.get(i);
                    int to = augmentedPath.get(i + 1);
                    capacity[from][to] -= minFlow;
                    capacity[to][from] += minFlow;
                }
                totalFlow += minFlow;
                augmentedPath.clear();
            }
            return totalFlow;
        }

        private boolean getAugmentedPath(List<Integer> augmentedPath) {
            Queue<Integer> q = new ArrayDeque<>();
            int[] parent = new int[cntNodes + 1];
            boolean[] visited = new boolean[cntNodes + 1];
            Arrays.fill(visited, false);
            q.add(sourceNode);
            while (!q.isEmpty()) {
                int top = q.poll();
                visited[top] = true;
                for (int i = 1; i <= cntNodes; ++i) {
                    if (!visited[i] && capacity[top][i] > 0) {
                        q.add(i);
                        parent[i] = top;
                    }
                }
            }
            if (!visited[destNode]) {
                return false;
            }
            for (int node = destNode; node != sourceNode; node = parent[node]) {
                augmentedPath.add(node);
            }
            augmentedPath.add(sourceNode);
            Collections.reverse(augmentedPath);
            return true;
        }
    }
}