Ejemplo n.º 1
0
        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)));
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        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);
                }
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        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)));
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
        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;
                        }
                    }
                });
            }
        }
Ejemplo n.º 10
0
        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))));
        }