using
System;
using
System.Collections.Generic;
class
Edge {
public
int
v;
public
int
flow;
public
int
C;
public
int
rev;
public
Edge(
int
v,
int
flow,
int
C,
int
rev) {
this
.v = v;
this
.flow = flow;
this
.C = C;
this
.rev = rev;
}
}
class
Graph {
private
int
V;
private
int
[] level;
private
List<Edge>[] adj;
public
Graph(
int
V) {
adj =
new
List<Edge>[V];
for
(
int
i = 0; i < V; i++) {
adj[i] =
new
List<Edge>();
}
this
.V = V;
level =
new
int
[V];
}
public
void
addEdge(
int
u,
int
v,
int
C) {
Edge a =
new
Edge(v, 0, C, adj[v].Count);
Edge b =
new
Edge(u, 0, 0, adj[u].Count);
adj[u].Add(a);
adj[v].Add(b);
}
public
bool
BFS(
int
s,
int
t) {
for
(
int
j = 0; j < V; j++) {
level[j] = -1;
}
level[s] = 0;
Queue<
int
> q =
new
Queue<
int
>();
q.Enqueue(s);
List<Edge>.Enumerator i;
while
(q.Count != 0) {
int
u = q.Dequeue();
for
(i = adj[u].GetEnumerator(); i.MoveNext();) {
Edge e = i.Current;
if
(level[e.v] < 0 && e.flow < e.C) {
level[e.v] = level[u] + 1;
q.Enqueue(e.v);
}
}
}
return
level[t] < 0 ?
false
:
true
;
}
public
int
sendFlow(
int
u,
int
flow,
int
t,
int
[] start) {
if
(u == t) {
return
flow;
}
for
(; start[u] < adj[u].Count; start[u]++) {
Edge e = adj[u][start[u]];
if
(level[e.v] == level[u] + 1 && e.flow < e.C) {
int
curr_flow = Math.Min(flow, e.C - e.flow);
int
temp_flow = sendFlow(e.v, curr_flow, t, start);
if
(temp_flow > 0) {
e.flow += temp_flow;
adj[e.v][e.rev].flow -= temp_flow;
return
temp_flow;
}
}
}
return
0;
}
public
int
DinicMaxflow(
int
s,
int
t) {
if
(s == t) {
return
-1;
}
int
total = 0;
while
(BFS(s, t) ==
true
) {
int
[] start =
new
int
[V + 1];
while
(
true
) {
int
flow = sendFlow(s,
int
.MaxValue, t, start);
if
(flow == 0) {
break
;
}
total += flow;
}
}
return
total;
}
}
public
class
Gfg {
public
static
void
Main() {
Graph g =
new
Graph(6);
g.addEdge(0, 1, 16);
g.addEdge(0, 2, 13);
g.addEdge(1, 2, 10);
g.addEdge(1, 3, 12);
g.addEdge(2, 1, 4);
g.addEdge(2, 4, 14);
g.addEdge(3, 2, 9);
g.addEdge(3, 5, 20);
g.addEdge(4, 3, 7);
g.addEdge(4, 5, 4);
Console.Write(
"Maximum flow "
+ g.DinicMaxflow(0, 5));
}
}