Pagini recente » Diferente pentru utilizator/samoila_alexandru intre reviziile 5 si 6 | Diferente pentru problema/dedicatie intre reviziile 15 si 75 | Statistici Carp Theodor-Nicolae (theodor.nicolae) | Diferente pentru utilizator/djok intre reviziile 119 si 118 | Cod sursa (job #2088891)
import java.io.*;
import java.util.*;
public class Main {
private static final String INPUT_FILE_PATH = "maxflow.in";
private static final String OUTPUT_FILE_PATH = "maxflow.out";
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new FileReader(INPUT_FILE_PATH));
PrintWriter out = new PrintWriter(OUTPUT_FILE_PATH);
int n = in.nextInt();
int m = in.nextInt();
DirectedGraph mGraph = new DirectedGraph(n);
while (m-- > 0) {
int source = in.nextInt();
int dest = in.nextInt();
int cap = in.nextInt();
mGraph.link(source, dest, cap);
}
out.println(mGraph.getMaxFlow(1, n));
in.close();
out.close();
}
static class DirectedGraph {
private static final int UNREACHABLE_NODE = -1;
private int nodes;
private List<Map<Integer, Integer>> adjList;
public DirectedGraph(int n) {
this.nodes = n;
adjList = new ArrayList<>(n + 1);
while (n-- > -1) {
adjList.add(new HashMap<>());
}
}
public void link(int source, int dest, int capacity) {
adjList.get(source).put(dest, capacity);
}
public int getMaxFlow(int source, int dest) {
int[] prev = new int[this.nodes + 1];
int maxFlow = 0;
while ((prev = getBFSTree(source))[dest] != UNREACHABLE_NODE) {
if (prev[dest] != UNREACHABLE_NODE) {
int localMaxFlow = Integer.MAX_VALUE;
for (int node = dest; node != source; node = prev[node]) {
int currEdgeCapacity = this.adjList.get(prev[node]).get(node);
localMaxFlow = Math.min(localMaxFlow, currEdgeCapacity);
}
for (int node = dest; node != source; node = prev[node]) {
int oldCapacity = this.adjList.get(prev[node]).get(node);
this.adjList.get(prev[node]).put(node, oldCapacity - localMaxFlow);
}
maxFlow += localMaxFlow;
}
}
return maxFlow;
}
private int[] getBFSTree(int source) {
int[] prev = new int[this.nodes + 1];
Arrays.fill(prev, UNREACHABLE_NODE);
prev[source] = source;
boolean[] used = new boolean[this.nodes + 1];
Arrays.fill(used, false);
used[source] = true;
Queue<Integer> queue = new ArrayDeque<>();
queue.add(source);
while (!queue.isEmpty()) {
int currNode = queue.poll();
for (Map.Entry<Integer, Integer> edge : this.adjList.get(currNode).entrySet()) {
int capacity = edge.getValue();
int neighb = edge.getKey();
if (!used[neighb] && capacity > 0) {
used[neighb] = true;
prev[neighb] = currNode;
queue.add(neighb);
}
}
}
return prev;
}
}
}