Cod sursa(job #2088898)

Utilizator abitlazyabitlazy abitlazy Data 15 decembrie 2017 23:46:28
Problema Flux maxim Scor 40
Compilator java Status done
Runda Arhiva educationala Marime 2.58 kb
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;
			this.adjList = new ArrayList<>(n + 1);
			while (n-- > -1) {
				this.adjList.add(new HashMap<Integer, Integer>());
			}
		}

		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;
		}
	}

}