private static int FindPath(int source, int sink, int numVertices)
{
Queue<int> queue = new Queue<int>();
bool[] visited = new bool[numVertices];
int[] from = new int[numVertices];
for (int i = 0; i < numVertices; i++)
from[i] = SENTINEL;
//push source to queue and mark visited
queue.Enqueue(source);
visited[source] = true;
//do the breadth first search to create a path
while (queue.Count > 0)
{
int current = queue.Dequeue();
bool foundEnd = false;
for (int adj = 0; adj < numVertices; adj++)
{
//skip current one
if (adj == current)
continue;
//if no capacity, skip over
if (matrix[current, adj] <= 0)
continue;
//if its not visited and has capacity
//enque it and mark visited
if (!visited[adj])
{
queue.Enqueue(adj);
visited[adj] = true;
from[adj] = current;
}
if (adj == sink)
{
//exit outer loop
foundEnd = true;
break;
}
}
if (foundEnd)
break;
}
// compute path capacity – walk back along path
int curr = sink;
int prev;
int pathCap = int.MaxValue;
//capacity is the minimum value in the path
while (from[curr] != SENTINEL)
{
prev = from[curr];
pathCap = Math.Min(pathCap, matrix[prev, curr]);
curr = prev;
}
//update the residual network
//so taht we can check in future for another augmenting path
// another augmenting path = more flow that can fit through network.
curr = sink;
//while there is a path
while (from[curr] != SENTINEL)
{
//get the previous node
prev = from[curr];
//take the capacity away from the forward path
matrix[prev, curr] -= pathCap;
//add the flow going through to the backward path.
matrix[curr, prev] += pathCap;
curr = prev;
}
if (pathCap == int.MaxValue)
pathCap = 0;
return pathCap;
}