Skip to content

Commit 6d83427

Browse files
committed
add stress test for mincostflow
1 parent aaaf8bc commit 6d83427

File tree

1 file changed

+70
-1
lines changed

1 file changed

+70
-1
lines changed

test/unittest/mincostflow_test.cpp

+70-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
#include <atcoder/maxflow>
12
#include <atcoder/mincostflow>
3+
24
#include <numeric>
35
#include <tuple>
46
#include <vector>
7+
#include "../utils/random.hpp"
58

69
#include <gtest/gtest.h>
710

@@ -66,7 +69,7 @@ TEST(MincostflowTest, Assign) {
6669

6770
TEST(MincostflowTest, OutOfRange) {
6871
mcf_graph<int, int> g(10);
69-
72+
7073
EXPECT_DEATH(g.slope(-1, 3), ".*");
7174
EXPECT_DEATH(g.slope(3, 3), ".*");
7275
}
@@ -95,3 +98,69 @@ TEST(MincostflowTest, Invalid) {
9598
EXPECT_DEATH(g.add_edge(0, 0, -1, 0), ".*");
9699
EXPECT_DEATH(g.add_edge(0, 0, 0, -1), ".*");
97100
}
101+
102+
TEST(MincostflowTest, Stress) {
103+
for (int phase = 0; phase < 1000; phase++) {
104+
int n = randint(2, 20);
105+
int m = randint(1, 100);
106+
int s, t;
107+
std::tie(s, t) = randpair(0, n - 1);
108+
if (randbool()) std::swap(s, t);
109+
110+
mf_graph<int> g_mf(n);
111+
mcf_graph<int, int> g(n);
112+
for (int i = 0; i < m; i++) {
113+
int u = randint(0, n - 1);
114+
int v = randint(0, n - 1);
115+
int cap = randint(0, 10);
116+
int cost = randint(0, 10000);
117+
g.add_edge(u, v, cap, cost);
118+
g_mf.add_edge(u, v, cap);
119+
}
120+
int flow, cost;
121+
std::tie(flow, cost) = g.flow(s, t);
122+
ASSERT_EQ(g_mf.flow(s, t), flow);
123+
124+
int cost2 = 0;
125+
std::vector<int> v_cap(n);
126+
for (auto e : g.edges()) {
127+
v_cap[e.from] -= e.flow;
128+
v_cap[e.to] += e.flow;
129+
cost2 += e.flow * e.cost;
130+
}
131+
ASSERT_EQ(cost, cost2);
132+
133+
for (int i = 0; i < n; i++) {
134+
if (i == s) {
135+
ASSERT_EQ(-flow, v_cap[i]);
136+
} else if (i == t) {
137+
ASSERT_EQ(flow, v_cap[i]);
138+
} else {
139+
ASSERT_EQ(0, v_cap[i]);
140+
}
141+
}
142+
143+
// check: there is no negative-cycle
144+
std::vector<int> dist(n);
145+
while (true) {
146+
bool update = false;
147+
for (auto e : g.edges()) {
148+
if (e.flow < e.cap) {
149+
int ndist = dist[e.from] + e.cost;
150+
if (ndist < dist[e.to]) {
151+
update = true;
152+
dist[e.to] = ndist;
153+
}
154+
}
155+
if (e.flow) {
156+
int ndist = dist[e.to] - e.cost;
157+
if (ndist < dist[e.from]) {
158+
update = true;
159+
dist[e.from] = ndist;
160+
}
161+
}
162+
}
163+
if (!update) break;
164+
}
165+
}
166+
}

0 commit comments

Comments
 (0)