Skip to content

Commit 500b2d7

Browse files
authored
Merge pull request #32 from atcoder/patch/stress
add simple stress test for twosat,maxflow
2 parents 2fa53a2 + 31ac0ca commit 500b2d7

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

test/unittest/maxflow_test.cpp

+36-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <numeric>
55
#include <tuple>
66
#include <vector>
7+
#include "../utils/random.hpp"
78

89
using namespace atcoder;
910
using ll = long long;
@@ -184,4 +185,38 @@ TEST(MaxflowTest, Invalid) {
184185
// https://github.com/atcoder/ac-library/issues/5
185186
EXPECT_DEATH(g.flow(0, 0), ".*");
186187
EXPECT_DEATH(g.flow(0, 0, 0), ".*");
187-
}
188+
}
189+
190+
TEST(MaxflowTest, Stress) {
191+
for (int phase = 0; phase < 10000; phase++) {
192+
int n = randint(2, 20);
193+
int m = randint(1, 100);
194+
int s, t;
195+
std::tie(s, t) = randpair(0, n - 1);
196+
if (randbool()) std::swap(s, t);
197+
198+
mf_graph<int> g(n);
199+
for (int i = 0; i < m; i++) {
200+
int u = randint(0, n - 1);
201+
int v = randint(0, n - 1);
202+
int c = randint(0, 10000);
203+
g.add_edge(u, v, c);
204+
}
205+
int flow = g.flow(s, t);
206+
int dual = 0;
207+
auto cut = g.min_cut(s);
208+
std::vector<int> v_flow(n);
209+
for (auto e: g.edges()) {
210+
v_flow[e.from] -= e.flow;
211+
v_flow[e.to] += e.flow;
212+
if (cut[e.from] && !cut[e.to]) dual += e.cap;
213+
}
214+
ASSERT_EQ(flow, dual);
215+
ASSERT_EQ(-flow, v_flow[s]);
216+
ASSERT_EQ(flow, v_flow[t]);
217+
for (int i = 0; i < n; i++) {
218+
if (i == s || i == t) continue;
219+
ASSERT_EQ(0, v_flow[i]);
220+
}
221+
}
222+
}

test/unittest/twosat_test.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <atcoder/twosat>
44
#include <numeric>
55

6+
#include "../utils/random.hpp"
7+
68
using namespace atcoder;
79
using ll = long long;
810
using ull = unsigned long long;
@@ -41,3 +43,43 @@ TEST(TwosatTest, Assign) {
4143
two_sat ts;
4244
ts = two_sat(10);
4345
}
46+
47+
TEST(TwosatTest, StressOK) {
48+
for (int phase = 0; phase < 10000; phase++) {
49+
int n = randint(1, 20);
50+
int m = randint(1, 100);
51+
std::vector<bool> expect(n);
52+
for (int i = 0; i < n; i++) {
53+
expect[i] = randbool();
54+
}
55+
two_sat ts(n);
56+
std::vector<int> xs(m), ys(m), types(m);
57+
for (int i = 0; i < m; i++) {
58+
int x = randint(0, n - 1);
59+
int y = randint(0, n - 1);
60+
int type = randint(0, 2);
61+
xs[i] = x;
62+
ys[i] = y;
63+
types[i] = type;
64+
if (type == 0) {
65+
ts.add_clause(x, expect[x], y, expect[y]);
66+
} else if (type == 1) {
67+
ts.add_clause(x, !expect[x], y, expect[y]);
68+
} else {
69+
ts.add_clause(x, expect[x], y, !expect[y]);
70+
}
71+
}
72+
ASSERT_TRUE(ts.satisfiable());
73+
auto actual = ts.answer();
74+
for (int i = 0; i < m; i++) {
75+
int x = xs[i], y = ys[i], type = types[i];
76+
if (type == 0) {
77+
ASSERT_TRUE(actual[x] == expect[x] || actual[y] == expect[y]);
78+
} else if (type == 1) {
79+
ASSERT_TRUE(actual[x] != expect[x] || actual[y] == expect[y]);
80+
} else {
81+
ASSERT_TRUE(actual[x] == expect[x] || actual[y] != expect[y]);
82+
}
83+
}
84+
}
85+
}

test/utils/random.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ T randint(T a, T b) {
99
return std::uniform_int_distribution<T>(a, b)(global_mt19937);
1010
}
1111

12+
bool randbool() {
13+
return randint(0, 1) == 0;
14+
}
15+
1216
// random choice 2 disjoint elements from [lower, upper]
1317
template <class T> std::pair<T, T> randpair(T lower, T upper) {
1418
assert(upper - lower >= 1);

0 commit comments

Comments
 (0)