Pagini recente » Cod sursa (job #730945) | Istoria paginii home | Borderou de evaluare (job #1036189) | Cod sursa (job #2220749) | Cod sursa (job #1740046)
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(new FileInputStream("maxflow.in"));
int N = in.nextInt();
int M = in.nextInt();
MaxFlow MF = new MaxFlow(N);
for (int i = 0; i < M; i++) {
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();
MF.addEdge(a, b, c);
MF.addEdge(b, a, 0);
}
PrintWriter out = new PrintWriter(new FileOutputStream("maxflow.out"));
out.println(MF.maxFlow(1, N));
out.close();
}
static class MaxFlow{
private static class Edge{
int flow;
int capacity;
int node;
int next;
Edge(int flow, int capacity, int node, int next) {
this.flow = flow;
this.capacity = capacity;
this.node = node;
this.next = next;
}
}
private final int NIL = -1;
private ArrayList<Edge> G;
private int[] head, pointer, father;
private int N, contor;
MaxFlow(int N){
this.G = new ArrayList<>();
this.head = new int[N + 1];
this.pointer = new int[N + 1];
this.father = new int[N + 1];
this.N = N;
this.contor = 0;
for (int i = 1; i <= N; ++i)
this.head[i] = NIL;
}
void addEdge(int x, int y, int capacity){
G.add(new Edge(0, capacity, y, head[x]));
head[x] = contor++;
}
private boolean BFS(int S, int T){
for (int i = 1; i <= N; i++) {
pointer[i] = 0;
father[i] = 0;
}
Queue<Integer> queue = new LinkedList<>();
queue.add(S);
father[S] = S;
while (!queue.isEmpty()){
int node = queue.remove();
for (int p = head[node]; p != NIL; p = G.get(p).next) {
Edge e = G.get(p);
int son = e.node;
int flow = e.flow;
int capacity = e.capacity;
if (father[son] == 0 && capacity > flow){
father[son] = node;
pointer[son] = p;
if (son == T)
return true;
queue.add(son);
}
}
}
return false;
}
int maxFlow(int S, int T){
int totalFlow = 0;
while (BFS(S, T)){
for (int p = head[T]; p != NIL; p = G.get(p).next) {
int son = G.get(p).node;
if (father[son] != 0 && G.get(p ^ 1).capacity > G.get(p ^ 1).flow){
father[T] = son;
pointer[T] = p ^ 1;
int fmin = Integer.MAX_VALUE;
int node = T;
while (node != S){
Edge e = G.get(pointer[node]);
fmin = Math.min(fmin, e.capacity - e.flow);
node = father[node];
}
totalFlow += fmin;
node = T;
while (node != S){
G.get(pointer[node]).flow += fmin;
G.get(pointer[node] ^ 1).flow -= fmin;
node = father[node];
}
}
}
}
return totalFlow;
}
}
static class InputReader{
private BufferedReader reader;
private StringTokenizer tokenizer;
InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 65536);
tokenizer = null;
}
private String nextToken() {
while (tokenizer == null || !tokenizer.hasMoreTokens()){
try {
tokenizer = new StringTokenizer(reader.readLine());
}
catch (IOException e){
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
int nextInt() {
return Integer.parseInt(nextToken());
}
String nextString(){
return nextToken();
}
}
}