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 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 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; } } }); } }