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)));
        }
Esempio n. 2
0
        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;
                        }
                    }
                });
            }
        }