public void ArgumentExceptionInAddEdge() { var fg = new FlowGraph(2); Assert.Throws <ArgumentException>(() => fg.AddEdge(0, 0, -1)); Assert.Throws <ArgumentException>(() => fg.AddEdge(0, 0, 0, -1)); }
/// <summary> /// Berechnet zu einem Flussgraphen den Residual-Graphen. /// </summary> /// <typeparam name="T">Der Datentyp des Graphen.</typeparam> /// <param name="graph">Der Graph.</param> /// <returns>Der Residualgraph.</returns> public static FlowGraph <T> GetResidualGraph <T> (this FlowGraph <T> graph) { if (graph.Edges.Where(e => !e.Capacity.HasValue).Any()) { throw new ArgumentException("In dem Graphen muss für jede Kante eine Kapazität definiert sein."); } // Sicherstellen, dass der Fluss bei allen Kanten initialisiert ist. foreach (Edge <T> e in graph.Edges.Where(e => !e.Flow.HasValue)) { e.Flow = 0; } FlowGraph <T> residualGraph = new FlowGraph <T>(graph.Source.Value, graph.Target.Value, graph.Vertices.Select(v => v.Value), isDirected: true); foreach (Edge <T> e in graph.Edges) { if ((e.Capacity - e.Flow) > 0) { residualGraph.AddEdge(e.From, e.To, capacity: e.Capacity.Value, flow: e.Capacity.Value - e.Flow.Value); } if (e.Flow > 0) { residualGraph.AddEdge(e.To, e.From, capacity: e.Capacity.Value, flow: e.Flow.Value * (-1)); } } return(residualGraph); }
public void MaxFlowTwiceTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 2, 1), Is.EqualTo(1)); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(2)); Assert.That(fg.MaxFlow(0, 2), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); fg.ChangeEdge(0, 100, 10); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 10))); Assert.That(fg.MaxFlow(0, 2), Is.Zero); Assert.That(fg.MaxFlow(0, 1), Is.EqualTo(90)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 100))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); Assert.That(fg.MaxFlow(2, 0), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 100, 99))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 0))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0))); }
public static void Solve() { var(N, G, E) = Scanner.Scan <int, int, int>(); if (G == 0) { Console.WriteLine(0); return; } var P = Scanner.ScanEnumerable <int>().ToArray(); var fg = new FlowGraph(N + 1); foreach (var p in P) { fg.AddEdge(p, N, 1); } for (var i = 0; i < E; i++) { var(a, b) = Scanner.Scan <int, int>(); fg.AddEdge(a, b, 1); fg.AddEdge(b, a, 1); } var answer = fg.MaxFlow(0, N); Console.WriteLine(answer); }
public void ArgumentOutOfRangeExceptionInChangeEdge([Values(-1, 3)] int v) { var fg = new FlowGraph(3); fg.AddEdge(0, 1, 100); fg.AddEdge(1, 2, 100); Assert.Throws <ArgumentOutOfRangeException>(() => fg.ChangeEdge(v, 100, 10)); }
public void ArgumentExceptionInChangeEdge([Values(-10, 100)] int newFlow) { var fg = new FlowGraph(3); fg.AddEdge(0, 1, 100); fg.AddEdge(1, 2, 100); Assert.Throws <ArgumentException>(() => fg.ChangeEdge(1, 10, newFlow)); }
public void ArgumentOutOfRangeExceptionInMaxFlow(int u, int v) { var fg = new FlowGraph(3); fg.AddEdge(0, 1, 100); fg.AddEdge(1, 2, 100); Assert.Throws <ArgumentOutOfRangeException>(() => fg.MaxFlow(u, v)); }
public void ArgumentOutOfRangeExceptionInAddEdgeAndGetEdge([Values(-1, 3)] int v) { var fg = new FlowGraph(3); Assert.Throws <ArgumentOutOfRangeException>(() => fg.AddEdge(v, 1, 10)); Assert.Throws <ArgumentOutOfRangeException>(() => fg.AddEdge(0, v, 10)); Assert.Throws <ArgumentOutOfRangeException>(() => fg.GetEdge(v)); }
public void ArgumentExceptionInMaxFlow() { var fg = new FlowGraph(3); fg.AddEdge(0, 1, 100); fg.AddEdge(1, 2, 100); Assert.Throws <ArgumentException>(() => fg.MaxFlow(0, 0)); Assert.Throws <ArgumentException>(() => fg.MaxFlow(0, 0, 0)); }
public void MinCostFlowSameCostPathsTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 1, 1, 1), Is.Zero); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(1)); Assert.That(fg.AddEdge(0, 2, 2, 1), Is.EqualTo(2)); var actual = fg.MinCostSlope(0, 2).ToArray(); Assert.That(actual[0], Is.EqualTo((0, 0))); Assert.That(actual[1], Is.EqualTo((3, 3))); }
public void MinCostFlowSelfLoopTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 0, 100, 123), Is.Zero); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 0, 100, 0, 123))); }
public void MaxFlowSimpleTest() { var fg = new FlowGraph(4); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 2, 1), Is.EqualTo(1)); Assert.That(fg.AddEdge(1, 3, 1), Is.EqualTo(2)); Assert.That(fg.AddEdge(2, 3, 1), Is.EqualTo(3)); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(4)); Assert.That(fg.MaxFlow(0, 3), Is.EqualTo(2)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 3, 1, 1))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(2, 3, 1, 1))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0))); }
public void MaxFlowMinCutTest() { var fg = new FlowGraph(3); Assert.That(fg.AddEdge(0, 1, 2), Is.Zero); Assert.That(fg.AddEdge(1, 2, 1), Is.EqualTo(1)); Assert.That(fg.MaxFlow(0, 2), Is.EqualTo(1)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 2, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 1))); var minCut = fg.MinCut(0); Assert.That(minCut[0], Is.True); Assert.That(minCut[1], Is.True); Assert.That(minCut[2], Is.False); }
public void MinCostFlowSimpleTest() { var fg = new FlowGraph(4); fg.AddEdge(0, 1, 1, 1); fg.AddEdge(0, 2, 1, 1); fg.AddEdge(1, 3, 1, 1); fg.AddEdge(2, 3, 1, 1); fg.AddEdge(1, 2, 1, 1); var actual = fg.MinCostSlope(0, 3, 10).ToArray(); Assert.That(actual[0], Is.EqualTo((0, 0))); Assert.That(actual[1], Is.EqualTo((2, 4))); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 2, 1, 1, 1))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(1, 3, 1, 1, 1))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(2, 3, 1, 1, 1))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(1, 2, 1, 0, 1))); }
public static void Solve() { var NK = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); var(N, K) = (NK[0], NK[1]); var A = new long[N][].Select(x => Console.ReadLine().Split(" ").Select(long.Parse).ToArray()) .ToArray(); var fg = new FlowGraph(N * 2 + 2); var s = N * 2; var t = N * 2 + 1; const long inf = (long)1e9; fg.AddEdge(s, t, N * K, inf); for (var i = 0; i < N; i++) { fg.AddEdge(s, i, K); fg.AddEdge(N + i, t, K); } for (var i = 0; i < N; i++) { for (var j = 0; j < N; j++) { fg.AddEdge(i, N + j, 1, inf - A[i][j]); } } var result = fg.MinCostFlow(s, t, N * K); Console.WriteLine(inf * N * K - result.Item2); var G = new char[N][].Select(x => Enumerable.Repeat('.', N).ToArray()).ToArray(); foreach (var edge in fg.GetEdges().Where(x => x.From != s && x.To != t && x.Flow != 0)) { G[edge.From][edge.To - N] = 'X'; } Console.WriteLine(string.Join("\n", G.Select(x => new string(x)))); }
public void UsageTest() { var fg = new FlowGraph(2); fg.AddEdge(0, 1, 1, 2); Assert.That(fg.MinCostFlow(0, 1), Is.EqualTo((1, 2))); fg = new FlowGraph(2); fg.AddEdge(0, 1, 1, 2); var actual = fg.MinCostSlope(0, 1).ToArray(); Assert.That(actual[0], Is.EqualTo((0, 0))); Assert.That(actual[1], Is.EqualTo((1, 2))); }
public void MaxFlowStressTest() { for (var ph = 0; ph < 10000; ph++) { var n = Utilities.RandomInteger(2, 20); var m = Utilities.RandomInteger(1, 100); var(s, t) = Utilities.RandomPair(0, n - 1); if (Utilities.RandomBool()) { (s, t) = (t, s); } var fg = new FlowGraph(n); for (var i = 0; i < m; i++) { var u = Utilities.RandomInteger(0, n - 1); var v = Utilities.RandomInteger(0, n - 1); var c = Utilities.RandomInteger(0, 10000); fg.AddEdge(u, v, c); } var flow = fg.MaxFlow(s, t); var dual = 0L; var minCut = fg.MinCut(s); var flows = new long[n]; foreach (var edge in fg.GetEdges()) { flows[edge.From] -= edge.Flow; flows[edge.To] += edge.Flow; if (minCut[edge.From] && !minCut[edge.To]) { dual += edge.Capacity; } } Assert.That(dual, Is.EqualTo(flow)); Assert.That(flows[s], Is.EqualTo(-flow)); Assert.That(flows[t], Is.EqualTo(flow)); for (var i = 0; i < n; i++) { if (i == s || i == t) { continue; } Assert.That(flows[i], Is.Zero); } } }
public void Copy_must_work() { Vertex<string> source = new Vertex<string>("s"); Vertex<string> target = new Vertex<string>("t"); FlowGraph<string> flowGraph = new FlowGraph<string>(source, target, new List<Vertex<string>>() { source, target }); flowGraph.AddVertex("a"); flowGraph.AddVertex("b"); flowGraph.AddEdge("s", "a", 5, 2); flowGraph.AddEdge("s", "b", 8, 4); flowGraph.AddEdge("a", "b", 3, 0); flowGraph.AddEdge("a", "t", 4, 2); flowGraph.AddEdge("b", "t", 6, 4); FlowGraph<string> flowGraphCopy = flowGraph.Copy(); Assert.IsFalse(ReferenceEquals(flowGraph.Vertices, flowGraphCopy.Vertices)); Assert.IsFalse(ReferenceEquals(flowGraph.Edges, flowGraphCopy.Edges)); Assert.IsFalse(ReferenceEquals(flowGraph.Vertices[0], flowGraphCopy.Vertices[0])); Assert.IsFalse(ReferenceEquals(flowGraph.Edges[0], flowGraphCopy.Edges[0])); }
public void MaxFlowComplexTest() { var fg = new FlowGraph(2); Assert.That(fg.AddEdge(0, 1, 1), Is.Zero); Assert.That(fg.AddEdge(0, 1, 2), Is.EqualTo(1)); Assert.That(fg.AddEdge(0, 1, 3), Is.EqualTo(2)); Assert.That(fg.AddEdge(0, 1, 4), Is.EqualTo(3)); Assert.That(fg.AddEdge(0, 1, 5), Is.EqualTo(4)); Assert.That(fg.AddEdge(0, 0, 6), Is.EqualTo(5)); Assert.That(fg.AddEdge(1, 1, 7), Is.EqualTo(6)); Assert.That(fg.MaxFlow(0, 1), Is.EqualTo(15)); Assert.That(fg.GetEdge(0), Is.EqualTo(new FlowGraph.Edge(0, 1, 1, 1))); Assert.That(fg.GetEdge(1), Is.EqualTo(new FlowGraph.Edge(0, 1, 2, 2))); Assert.That(fg.GetEdge(2), Is.EqualTo(new FlowGraph.Edge(0, 1, 3, 3))); Assert.That(fg.GetEdge(3), Is.EqualTo(new FlowGraph.Edge(0, 1, 4, 4))); Assert.That(fg.GetEdge(4), Is.EqualTo(new FlowGraph.Edge(0, 1, 5, 5))); var minCut = fg.MinCut(0); Assert.That(minCut[0], Is.True); Assert.That(minCut[1], Is.False); }
public void FordFulkerson_must_work() { // Quelle und Senke erstellen. Vertex <string> source = new Vertex <string>("s"); Vertex <string> target = new Vertex <string>("t"); // alle weiteren Knoten des Graphens erstellen. Vertex <string> vA = new Vertex <string>("a"); Vertex <string> vB = new Vertex <string>("b"); Vertex <string> vC = new Vertex <string>("c"); Vertex <string> vD = new Vertex <string>("d"); // Den Graphen erstellen. FlowGraph <string> flowGraph = new FlowGraph <string>(source, target, new List <Vertex <string> >() { source, vA, vB, vC, vD, target }); // Die Kanten des Graphens erstellen. flowGraph.AddEdge("s", "a", capacity: 5, flow: 5); flowGraph.AddEdge("s", "b", capacity: 7, flow: 3); flowGraph.AddEdge("a", "b", capacity: 7, flow: 3); flowGraph.AddEdge("a", "c", capacity: 4, flow: 2); flowGraph.AddEdge("b", "c", capacity: 3, flow: 3); flowGraph.AddEdge("b", "d", capacity: 3, flow: 3); flowGraph.AddEdge("c", "d", capacity: 4, flow: 0); flowGraph.AddEdge("c", "t", capacity: 5, flow: 5); flowGraph.AddEdge("d", "t", capacity: 6, flow: 3); FlowGraph <string> maxFlowGraph = flowGraph.FordFulkerson(); // Die Flüsse über die Kanten überprüfen. Assert.AreEqual(5, maxFlowGraph.Edges[0].Flow); Assert.AreEqual(5, maxFlowGraph.Edges[1].Flow); Assert.AreEqual(1, maxFlowGraph.Edges[2].Flow); Assert.AreEqual(4, maxFlowGraph.Edges[3].Flow); Assert.AreEqual(3, maxFlowGraph.Edges[4].Flow); Assert.AreEqual(3, maxFlowGraph.Edges[5].Flow); Assert.AreEqual(2, maxFlowGraph.Edges[6].Flow); Assert.AreEqual(5, maxFlowGraph.Edges[7].Flow); Assert.AreEqual(5, maxFlowGraph.Edges[8].Flow); // Die Kantenflüsse für den nächsten Test auf 0 setzen. flowGraph.Edges.ForEach(e => { e.Flow = 0; }); maxFlowGraph = flowGraph.FordFulkerson(); // Die Flüsse über die Kanten überprüfen. Assert.AreEqual(4, maxFlowGraph.Edges[0].Flow); Assert.AreEqual(6, maxFlowGraph.Edges[1].Flow); Assert.AreEqual(0, maxFlowGraph.Edges[2].Flow); Assert.AreEqual(4, maxFlowGraph.Edges[3].Flow); Assert.AreEqual(3, maxFlowGraph.Edges[4].Flow); Assert.AreEqual(3, maxFlowGraph.Edges[5].Flow); Assert.AreEqual(2, maxFlowGraph.Edges[6].Flow); Assert.AreEqual(5, maxFlowGraph.Edges[7].Flow); Assert.AreEqual(5, maxFlowGraph.Edges[8].Flow); }
public void MinCostFlowStressTest() { for (var ph = 0; ph < 1000; ph++) { var n = Utilities.RandomInteger(2, 20); var m = Utilities.RandomInteger(1, 100); var(s, t) = Utilities.RandomPair(0, n - 1); if (Utilities.RandomBool()) { (s, t) = (t, s); } var mfg = new FlowGraph(n); var mcfg = new FlowGraph(n); for (var i = 0; i < m; i++) { var u = Utilities.RandomInteger(0, n - 1); var v = Utilities.RandomInteger(0, n - 1); var cap = Utilities.RandomInteger(0, 10); var cost = Utilities.RandomInteger(0, 10000); mcfg.AddEdge(u, v, cap, cost); mfg.AddEdge(u, v, cap); } var(flow, cost1) = mcfg.MinCostFlow(s, t); Assert.That(flow, Is.EqualTo(mfg.MaxFlow(s, t))); var cost2 = 0L; var capacities = new long[n]; foreach (var edge in mcfg.GetEdges()) { capacities[edge.From] -= edge.Flow; capacities[edge.To] += edge.Flow; cost2 += edge.Flow * edge.Cost; } Assert.That(cost1, Is.EqualTo(cost2)); for (var i = 0; i < n; i++) { if (i == s) { Assert.That(capacities[i], Is.EqualTo(-flow)); } else if (i == t) { Assert.That(capacities[i], Is.EqualTo(flow)); } else { Assert.That(capacities[i], Is.EqualTo(0)); } } Assert.DoesNotThrow(() => { var dist = new long[n]; while (true) { var update = false; foreach (var edge in mcfg.GetEdges()) { if (edge.Flow < edge.Capacity) { var ndist = dist[edge.From] + edge.Cost; if (ndist < dist[edge.To]) { update = true; dist[edge.To] = ndist; } } if (edge.Flow == 0) { continue; } { var ndist = dist[edge.To] - edge.Cost; if (ndist < dist[edge.From]) { update = true; dist[edge.From] = ndist; } } } if (!update) { break; } } }); } }
public void GetResidualGraph_must_work() { // Quelle und Senke erstellen. Vertex <string> source = new Vertex <string>("s"); Vertex <string> target = new Vertex <string>("t"); // alle weiteren Knoten des Graphens erstellen. Vertex <string> vA = new Vertex <string>("a"); Vertex <string> vB = new Vertex <string>("b"); Vertex <string> vC = new Vertex <string>("c"); Vertex <string> vD = new Vertex <string>("d"); // Den Graphen erstellen. FlowGraph <string> flowGraph = new FlowGraph <string>(source, target, new List <Vertex <string> >() { source, vA, vB, vC, vD, target }); // Die Kanten des Graphens erstellen. flowGraph.AddEdge("s", "a", capacity: 5, flow: 5); flowGraph.AddEdge("s", "b", capacity: 7, flow: 3); flowGraph.AddEdge("a", "b", capacity: 7, flow: 3); flowGraph.AddEdge("a", "c", capacity: 4, flow: 2); flowGraph.AddEdge("b", "c", capacity: 3, flow: 3); flowGraph.AddEdge("b", "d", capacity: 3, flow: 3); flowGraph.AddEdge("c", "d", capacity: 4, flow: 0); flowGraph.AddEdge("c", "t", capacity: 5, flow: 5); flowGraph.AddEdge("d", "t", capacity: 6, flow: 3); FlowGraph <string> residualGraph = flowGraph.GetResidualGraph(); // Die Kanten überprüfen Assert.AreEqual(13, residualGraph.Edges.Count); // a --> s Assert.AreEqual(vA, residualGraph.Edges[0].From); Assert.AreEqual(source, residualGraph.Edges[0].To); Assert.AreEqual(5, residualGraph.Edges[0].Capacity); Assert.AreEqual(-5, residualGraph.Edges[0].Flow); // s --> b Assert.AreEqual(source, residualGraph.Edges[1].From); Assert.AreEqual(vB, residualGraph.Edges[1].To); Assert.AreEqual(7, residualGraph.Edges[1].Capacity); Assert.AreEqual(4, residualGraph.Edges[1].Flow); // b --> s Assert.AreEqual(vB, residualGraph.Edges[2].From); Assert.AreEqual(source, residualGraph.Edges[2].To); Assert.AreEqual(7, residualGraph.Edges[2].Capacity); Assert.AreEqual(-3, residualGraph.Edges[2].Flow); // a --> b Assert.AreEqual(vA, residualGraph.Edges[3].From); Assert.AreEqual(vB, residualGraph.Edges[3].To); Assert.AreEqual(7, residualGraph.Edges[3].Capacity); Assert.AreEqual(4, residualGraph.Edges[3].Flow); // b --> a Assert.AreEqual(vB, residualGraph.Edges[4].From); Assert.AreEqual(vA, residualGraph.Edges[4].To); Assert.AreEqual(7, residualGraph.Edges[4].Capacity); Assert.AreEqual(-3, residualGraph.Edges[4].Flow); // a --> c Assert.AreEqual(vA, residualGraph.Edges[5].From); Assert.AreEqual(vC, residualGraph.Edges[5].To); Assert.AreEqual(4, residualGraph.Edges[5].Capacity); Assert.AreEqual(2, residualGraph.Edges[5].Flow); // c --> a Assert.AreEqual(vC, residualGraph.Edges[6].From); Assert.AreEqual(vA, residualGraph.Edges[6].To); Assert.AreEqual(4, residualGraph.Edges[6].Capacity); Assert.AreEqual(-2, residualGraph.Edges[6].Flow); // c --> b Assert.AreEqual(vC, residualGraph.Edges[7].From); Assert.AreEqual(vB, residualGraph.Edges[7].To); Assert.AreEqual(3, residualGraph.Edges[7].Capacity); Assert.AreEqual(-3, residualGraph.Edges[7].Flow); // d --> b Assert.AreEqual(vD, residualGraph.Edges[8].From); Assert.AreEqual(vB, residualGraph.Edges[8].To); Assert.AreEqual(3, residualGraph.Edges[8].Capacity); Assert.AreEqual(-3, residualGraph.Edges[8].Flow); // c --> d Assert.AreEqual(vC, residualGraph.Edges[9].From); Assert.AreEqual(vD, residualGraph.Edges[9].To); Assert.AreEqual(4, residualGraph.Edges[9].Capacity); Assert.AreEqual(4, residualGraph.Edges[9].Flow); // t --> c Assert.AreEqual(target, residualGraph.Edges[10].From); Assert.AreEqual(vC, residualGraph.Edges[10].To); Assert.AreEqual(5, residualGraph.Edges[10].Capacity); Assert.AreEqual(-5, residualGraph.Edges[10].Flow); // d --> t Assert.AreEqual(vD, residualGraph.Edges[11].From); Assert.AreEqual(target, residualGraph.Edges[11].To); Assert.AreEqual(6, residualGraph.Edges[11].Capacity); Assert.AreEqual(3, residualGraph.Edges[11].Flow); // t --> d Assert.AreEqual(target, residualGraph.Edges[12].From); Assert.AreEqual(vD, residualGraph.Edges[12].To); Assert.AreEqual(6, residualGraph.Edges[12].Capacity); Assert.AreEqual(-3, residualGraph.Edges[12].Flow); }
public static void Solve() { var NM = Console.ReadLine().Split(" ").Select(int.Parse).ToArray(); var(N, M) = (NM[0], NM[1]); var G = new char[N][].Select(x => Console.ReadLine().ToCharArray()).ToArray(); var fg = new FlowGraph(N * M + 2); var s = N * M; var t = N * M + 1; for (var i = 0; i < N; i++) { for (var j = 0; j < M; j++) { if (G[i][j] == '#') { continue; } var v = i * M + j; if ((i + j) % 2 == 0) { fg.AddEdge(s, v, 1); } else { fg.AddEdge(v, t, 1); } } } var di = new[] { -1, 0, 1, 0 }; var dj = new[] { 0, -1, 0, 1 }; for (var i = 0; i < N; i++) { for (var j = 0; j < M; j++) { if ((i + j) % 2 == 1 || G[i][j] == '#') { continue; } var v0 = i * M + j; for (var k = 0; k < 4; k++) { var ci = i + di[k]; var cj = j + dj[k]; if (ci < 0 || N <= ci) { continue; } if (cj < 0 || M <= cj) { continue; } if (G[ci][cj] != '.') { continue; } var v1 = ci * M + cj; fg.AddEdge(v0, v1, 1); } } } Console.WriteLine(fg.MaxFlow(s, t)); foreach (var edge in fg.GetEdges().Where(x => x.From != s && x.To != t && x.Flow != 0)) { var(i0, j0) = (edge.From / M, edge.From % M); var(i1, j1) = (edge.To / M, edge.To % M); if (i0 == i1 + 1) { G[i1][j1] = 'v'; G[i0][j0] = '^'; } else if (j0 == j1 + 1) { G[i1][j1] = '>'; G[i0][j0] = '<'; } else if (i0 == i1 - 1) { G[i0][j0] = 'v'; G[i1][j1] = '^'; } else { G[i0][j0] = '>'; G[i1][j1] = '<'; } } Console.WriteLine(string.Join("\n", G.Select(x => new string(x)))); }