#include <iostream>
#include <fstream>
#include <memory.h>
using namespace std;
// the maximum number of the vertexes
const int MaxN = 100;
const int MaxNum = 65535;
/* s: the soure node
* t: the sink node
* pathlen: the number of the vertexes in the augmentative path
* num: the number of the vertexes
* G[][]: the primal graph
* f[][]: the flow network
* path[]: the augmentative path
* pre[i]: the parent node of i, in order to obtain the path[] array
*/
int s, t, pathlen, num;
int G[MaxN][MaxN], f[MaxN][MaxN], path[MaxN], pre[MaxN];
// get the agumentative path, from a to b
void getPath (int a, int b)
{
if (a == b)
{
path[pathlen] = a;
}
else if (pre[b] != -1)
{
path[pathlen++] = b;
getPath (a, pre[b]);
}
}
// the Edmonds-Karp algorithm to solve the maximum flow problem
int Edmonds_Karp ()
{
//maxf stands for the maximum flow
int i, j, maxf;
//initial the primal flow by zeros
memset (f, 0, sizeof (f));
//using BFS method (Edmonds karp method) to get the 'augmentative path'
bool visit[MaxN], flag;
int q[MaxN], fir, l, vex, minc;
maxf = 0;
while (true)
{
memset (visit, false, sizeof (visit));
fir = l = 0;
q[l++] = s;
flag = false;
memset (pre, -1, sizeof (pre));
memset (path, 0, sizeof (path));
//BFS
visit[s] = true;
while (fir < l)
{
vex = q[fir++];
for (j = 0; j < num; j++)
{
if (G[vex][j] != f[vex][j] && visit[j] == false)
{
q[l++] = j;
visit[j] = true;
pre[j] = vex;
if (j == t)
{
flag = true;
break;
}
}
}
if (flag)
{
break;
}
}
// if there exists a augmentative path
if (flag)
{
pathlen = 0;
getPath (s, t);
minc = MaxNum;
int tmp;
//get the minmum augmentation
for (i = pathlen; i > 0; i--)
{
tmp = G[path[i]][path[i - 1]] - f[path[i]][path[i - 1]];
if (tmp < minc)
minc = tmp;
}
//update the flow network
for (i = pathlen; i > 0; i--)
{
f[path[i]][path[i - 1]] += minc;
f[path[i - 1]][path[i]] = 0 - f[path[i]][path[i - 1]];
}
}
else
{
for (j = 0; j < num; j++)
maxf += f[s][j];
break;
}
}
return maxf;
}
void initial ()
{
int i, j;
// a simple demo from the "introduction to algorithms-p657"
freopen ("input.txt", "r", stdin);
cin >> num;
if (num > MaxN)
{
cout << "error" << endl;
return;
}
cin >> s >> t;
for (i = 0; i < num; i++)
{
for (j = 0; j < num; j++)
cin >> G[i][j];
}
}
int main ()
{
int ans;
initial ();
ans = Edmonds_Karp ();
cout << "the maximum flow is: " << ans << endl;
return 0;
}