Cod sursa(job #927223)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
#define Nmax 1005
#define Mmax 5005
vector <int> graf[Nmax];
queue <int> q;
int c[Nmax][Nmax], t[Nmax], f[Nmax][Nmax]; // capacitatea & vectorul de tati in parcurgerea bfs & fluxul dintre noduri
int n, m, flow;
void read(){
int x, y, z;
scanf("%i %i", &n, &m);
for(int i = 1; i <= m; ++i){
scanf("%i %i %i", &x, &y, &z);
c[x][y] += z;
graf[x].push_back(y);
graf[y].push_back(x);
}
fclose(stdin);
}
int min(int a, int b){
if(a > b) return b;
return a;
}
int bfs(){
int u, v;
memset(t, -1, sizeof(t));
q.push(1);
while(!q.empty()){
u = q.front();
q.pop();
for(int i = 0, size = graf[u].size(); i < size; ++i){
v = graf[u][i];
if(t[v] == -1 && c[u][v] != f[u][v] ){ // adaug nodul in coada doar daca nu a mai fost vizitat si daca poate fi updatat
t[v] = u;
q.push(v);
}
}
}
if(t[n] == -1) return 0;
return 1;
}
void solve(){ // algoritmul lui Deric
int v, r;
while(bfs()){
for(int i = 0, size = graf[n].size(); i < size; ++i){
v = graf[n][i];
if(t[v] != -1 && c[v][n] != f[v][n]){
r = c[v][n] - f[v][n];
for(int j = v; j != 1; j = t[j]) // cauta valuare cu care pot actualiza fluxurile din drum
r = min(r, c[t[j]][j] - f[t[j]][j]);
f[v][n] += r;
f[n][v] -= r;
for(int j = v; j != 1; j = t[j]){ // actualizez fluxurile
f[t[j]][j] += r;
f[j][t[j]] -= r;
}
flow += r;
}
}
}
}
int main(){
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
read();
solve();
printf("%i\n", flow);
fclose(stdout);
return 0;
}