Skip to content

Commit 8947720

Browse files
committed
1 parent ed45c72 commit 8947720

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

Test/AtCoderLibrary.Test/Graph/MinCostFlowTest.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using FluentAssertions;
2+
using MersenneTwister;
23
using Xunit;
34

45
namespace AtCoder
@@ -78,5 +79,87 @@ public void Invalid()
7879
g.Invoking(g => g.AddEdge(0, 0, -1, 0)).Should().ThrowDebugAssertIfDebug();
7980
g.Invoking(g => g.AddEdge(0, 0, 0, -1)).Should().ThrowDebugAssertIfDebug();
8081
}
82+
83+
[Fact]
84+
public void Stress()
85+
{
86+
var mt = MTRandom.Create();
87+
for (int phase = 0; phase < 1000; phase++)
88+
{
89+
int n = mt.Next(2, 21);
90+
int m = mt.Next(1, 101);
91+
var (s, t) = mt.NextPair(0, n);
92+
if (mt.NextBool()) (s, t) = (t, s);
93+
94+
var gMf = new MFGraphInt(n);
95+
var g = new McfGraphInt(n);
96+
for (int i = 0; i < m; i++)
97+
{
98+
int u = mt.Next(0, n);
99+
int v = mt.Next(0, n);
100+
int cap = mt.Next(0, 11);
101+
int costIn = mt.Next(0, 10001);
102+
g.AddEdge(u, v, cap, costIn);
103+
gMf.AddEdge(u, v, cap);
104+
}
105+
var (flow, cost) = g.Flow(s, t);
106+
gMf.Flow(s, t).Should().Be(flow);
107+
108+
int cost2 = 0;
109+
var vCap = new int[n];
110+
foreach (var e in g.Edges())
111+
{
112+
vCap[e.From] -= e.Flow;
113+
vCap[e.To] += e.Flow;
114+
cost2 += e.Flow * e.Cost;
115+
}
116+
cost.Should().Be(cost2);
117+
118+
for (int i = 0; i < n; i++)
119+
{
120+
if (i == s)
121+
{
122+
(-flow).Should().Be(vCap[i]);
123+
}
124+
else if (i == t)
125+
{
126+
flow.Should().Be(vCap[i]);
127+
}
128+
else
129+
{
130+
vCap[i].Should().Be(0);
131+
}
132+
}
133+
134+
// check: there is no negative-cycle
135+
var dist = new int[n];
136+
while (true)
137+
{
138+
bool update = false;
139+
foreach (var e in g.Edges())
140+
{
141+
if (e.Flow < e.Cap)
142+
{
143+
int ndist = dist[e.From] + e.Cost;
144+
if (ndist < dist[e.To])
145+
{
146+
update = true;
147+
dist[e.To] = ndist;
148+
}
149+
}
150+
if (e.Flow != 0)
151+
{
152+
int ndist = dist[e.To] - e.Cost;
153+
if (ndist < dist[e.From])
154+
{
155+
update = true;
156+
dist[e.From] = ndist;
157+
}
158+
}
159+
}
160+
if (!update) break;
161+
}
162+
}
163+
}
81164
}
82165
}

0 commit comments

Comments
 (0)