using System.Collections.Generic;
private static readonly string[] map = {
private static readonly int ROWS = map.Length;
private static readonly int COLS = map[0].Length;
private static readonly int N = ROWS * COLS * 2;
public static void Main(string[] args)
int[,] C = ToCapacityMatrix();
Tuple<int, int[,]> fF = EdmondsKarp(C, s, t);
Console.WriteLine("Requires {0} walls.", f);
static void WriteWalls(int[,] C, int[,] F, int s)
HashSet<int> visited = Flood(C, F, s);
string[] newMap = new string[ROWS];
for(int r = 0; r < ROWS; ++r)
for (int u = 0; u < N; u += 2)
if (visited.Contains(u) && !visited.Contains(u + 1) && C[u, u + 1] > 0)
newMap[ToRow(u)] = newMap[ToRow(u)].Remove(ToCol(u), 1).Insert(ToCol(u), "W");
for (int r = 0; r < ROWS; ++r)
Console.WriteLine(newMap[r]);
static HashSet<int> Flood(int[,] C, int[,] F, int s)
HashSet<int> visited = new HashSet<int>();
Queue<int> queue = new Queue<int>();
for (int v = 0; v < N; ++v)
if ((C[u, v] - F[u, v]) > 0 && !visited.Contains(v))
for (int row = 0; row < ROWS; ++row)
for (int col = 0; col < COLS; ++col)
if (map[row][col] == '*')
return ToNodeOut(row, col);
for (int row = 0; row < ROWS; ++row)
for (int col = 0; col < COLS; ++col)
if (map[row][col] == 'o')
return ToNodeIn(row, col);
static int[,] ToCapacityMatrix()
int[,] C = new int[N, N];
for(int node = 0; node < N / 2; ++node) {
int row = ToRow(node * 2);
int col = ToCol(node * 2);
int nodeIn = ToNodeIn(row, col);
int nodeOut = ToNodeOut(row, col);
(map[row][col] == '-') ? 1 :
(map[row][col] == '#') ? 0 :
C[ToNodeOut(row - 1, col), nodeIn] = int.MaxValue;
C[ToNodeOut(row + 1, col), nodeIn] = int.MaxValue;
C[ToNodeOut(row, col - 1), nodeIn] = int.MaxValue;
C[ToNodeOut(row, col + 1), nodeIn] = int.MaxValue;
static int ToRow(int node)
static int ToCol(int node)
static int ToNodeIn(int row, int col)
return (row * COLS + col) * 2;
static int ToNodeOut(int row, int col)
return (row * COLS + col) * 2 + 1;
static Tuple<int, int[,]> EdmondsKarp(int[,] C, int s, int t)
int[,] F = new int[C.GetLength(1), C.GetLength(1)];
Tuple<int, int[]> mP = BreadthFirstSearch(C, s, t, F);
return new Tuple<int,int[,]>(f, F);
static Tuple<int, int[]> BreadthFirstSearch(int[,] C, int s, int t, int[,] F)
for (int u = 0; u < N; ++u)
Queue<int> Q = new Queue<int>();
for (int v = 0; v < N; ++v)
if ((C[u, v] - F[u, v] > 0) && (P[v] == -1))
M[v] = Math.Min(M[u], C[u, v] - F[u, v]);
return new Tuple<int, int[]>(M[t], P);
return new Tuple<int, int[]>(0, P);