Skip to content

Commit a5c0435

Browse files
lrvideckisweb-flow
andauthored
Dsu weighted (#192)
* first draft of dsu weighted * [auto-verifier] verify commit d124b1f * golf * [auto-verifier] verify commit 527432c * add aizu test now * [auto-verifier] verify commit f708280 * add docs now * [auto-verifier] verify commit 82effb2 * do it this way actually * [auto-verifier] verify commit 73cafbd * fix bug in test actually * [auto-verifier] verify commit 035c64c * fix+golf * [auto-verifier] verify commit b60cf61 * more golf * fix * another fix * another fix * [auto-verifier] verify commit 525fcf3 * one last optimization * [auto-verifier] verify commit bcd04c6 * one last fix --------- Co-authored-by: GitHub <noreply@github.com>
1 parent 9307635 commit a5c0435

7 files changed

Lines changed: 114 additions & 15 deletions

File tree

.verify-helper/timestamps.remote.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
"tests/library_checker_aizu_tests/data_structures/simple_tree_line.test.cpp": "2026-03-01 19:36:27 -0700",
4444
"tests/library_checker_aizu_tests/data_structures/simple_tree_walk.test.cpp": "2026-03-01 19:36:27 -0700",
4545
"tests/library_checker_aizu_tests/dsu/dsu.test.cpp": "2026-02-27 15:26:53 -0700",
46-
"tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp": "2026-02-27 15:26:53 -0700",
46+
"tests/library_checker_aizu_tests/dsu/dsu_bipartite.test.cpp": "2026-03-06 15:51:34 -0700",
47+
"tests/library_checker_aizu_tests/dsu/dsu_weighted_aizu.test.cpp": "2026-03-06 15:57:01 -0700",
48+
"tests/library_checker_aizu_tests/dsu/dsu_weighted_lib_checker.test.cpp": "2026-03-06 15:57:01 -0700",
4749
"tests/library_checker_aizu_tests/dsu/kruskal_tree_aizu.test.cpp": "2026-02-27 15:26:53 -0700",
4850
"tests/library_checker_aizu_tests/dsu/line_tree_aizu.test.cpp": "2026-02-27 15:26:53 -0700",
4951
"tests/library_checker_aizu_tests/dsu/line_tree_lib_checker.test.cpp": "2026-02-27 15:26:53 -0700",

library/dsu/dsu_bipartite.hpp

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,21 @@ struct dsu_bipartite {
88
int f(int v) {
99
if (p[v] < 0) return v;
1010
int root = f(p[v]);
11-
parity[v] ^= parity[p[v]];
12-
return p[v] = root;
11+
return parity[v] ^= parity[p[v]], p[v] = root;
1312
}
13+
int size(int v) { return -p[f(v)]; }
14+
bool is_bipartite(int v) { return is_bi[f(v)]; }
1415
bool join(int u, int v) {
15-
int root_u = f(u), root_v = f(v);
16-
int new_parity = parity[v] ^ parity[u];
17-
u = root_u, v = root_v;
18-
if (u == v) {
19-
is_bi[u] &= new_parity;
16+
int x = f(u), y = f(v);
17+
int new_parity = parity[u] ^ parity[v];
18+
if (x == y) {
19+
is_bi[x] &= new_parity;
2020
return 0;
2121
}
22-
if (p[u] > p[v]) swap(u, v);
23-
is_bi[u] &= is_bi[v];
24-
parity[v] = new_parity ^ 1;
25-
p[u] += p[v], p[v] = u;
22+
if (p[x] > p[y]) swap(x, y);
23+
is_bi[x] &= is_bi[y];
24+
parity[y] = new_parity ^ 1;
25+
p[x] += p[y], p[y] = x;
2626
return 1;
2727
}
28-
int size(int v) { return -p[f(v)]; }
29-
bool is_bipartite(int v) { return is_bi[f(v)]; }
3028
};

library/dsu/dsu_weighted.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
//! @code
3+
//! dsu_weighted dsu(n);
4+
//! dsu.join(u, v, w);
5+
//! // we now know a[u] = a[v] + w
6+
//! ll w = dsu.diff(u, v);
7+
//! // satisfies a[u] = a[v] + w based on prior joins
8+
//! @endcode
9+
//! @time O(n + q * \alpha(n))
10+
//! @space O(n)
11+
struct dsu_weighted {
12+
vi p;
13+
vector<ll> d;
14+
dsu_weighted(int n): p(n, -1), d(n) {}
15+
int f(int u) {
16+
if (p[u] < 0) return u;
17+
int root = f(p[u]);
18+
return d[u] += d[p[u]], p[u] = root;
19+
}
20+
int size(int u) { return -p[f(u)]; }
21+
ll diff(int u, int v) {
22+
return f(u) == f(v) ? d[v] - d[u] : 1e18;
23+
}
24+
bool join(int u, int v, ll w) {
25+
int x = f(u), y = f(v);
26+
if (x == y) return 0;
27+
w += d[u] - d[v];
28+
if (p[x] > p[y]) swap(x, y), w = -w;
29+
return p[x] += p[y], p[y] = x, d[y] = w, 1;
30+
}
31+
};

tests/.config/.cppcheck_suppression_list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ knownConditionTrueFalse:../library/strings/suffix_array/suffix_array.hpp:62
4343
knownConditionTrueFalse:../library/strings/suffix_array/suffix_array_short.hpp:34
4444
knownConditionTrueFalse:../library/dsu/kruskal_tree.hpp:13
4545
knownConditionTrueFalse:../library/dsu/dsu.hpp:11
46+
knownConditionTrueFalse:../library/dsu/dsu_weighted.hpp:29
4647
constVariable:../kactl/content/numerical/NumberTheoreticTransform.h:30
4748
constVariable:../kactl/content/graph/CompressTree.h:20
4849
constVariableReference:../kactl/content/graph/CompressTree.h:20
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#define PROBLEM \
2+
"https://onlinejudge.u-aizu.ac.jp/problems/DSL_1_B"
3+
#include "../template.hpp"
4+
#include "../../../library/dsu/dsu_weighted.hpp"
5+
#include "../../../library/dsu/dsu.hpp"
6+
int main() {
7+
cin.tie(0)->sync_with_stdio(0);
8+
int n, q;
9+
cin >> n >> q;
10+
dsu_weighted dsu_w(n);
11+
DSU dsu(n);
12+
while (q--) {
13+
int type, u, v;
14+
cin >> type >> u >> v;
15+
if (type == 0) {
16+
int w;
17+
cin >> w;
18+
dsu_w.join(u, v, w);
19+
dsu.join(u, v);
20+
assert(dsu.size(u) == dsu_w.size(u));
21+
assert(dsu.size(v) == dsu_w.size(v));
22+
} else {
23+
ll curr_diff = dsu_w.diff(u, v);
24+
if (curr_diff == ll(1e18)) cout << "?\n";
25+
else cout << dsu_w.diff(u, v) << '\n';
26+
assert(dsu.size(u) == dsu_w.size(u));
27+
assert(dsu.size(v) == dsu_w.size(v));
28+
}
29+
}
30+
return 0;
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#define PROBLEM \
2+
"https://judge.yosupo.jp/problem/unionfind_with_potential"
3+
#include "../template.hpp"
4+
#include "../../../library/dsu/dsu_weighted.hpp"
5+
#include "../../../library/dsu/dsu.hpp"
6+
const int mod = 998'244'353;
7+
int main() {
8+
cin.tie(0)->sync_with_stdio(0);
9+
int n, q;
10+
cin >> n >> q;
11+
dsu_weighted dsu_w(n);
12+
DSU dsu(n);
13+
while (q--) {
14+
int type, u, v;
15+
cin >> type >> u >> v;
16+
if (type == 0) {
17+
int w;
18+
cin >> w;
19+
bool joined = dsu_w.join(u, v, w);
20+
if (joined) cout << 1 << '\n';
21+
else
22+
cout << ((dsu_w.diff(u, v) % mod + mod) % mod == w)
23+
<< '\n';
24+
dsu.join(u, v);
25+
assert(dsu.size(u) == dsu_w.size(u));
26+
assert(dsu.size(v) == dsu_w.size(v));
27+
} else {
28+
ll curr_diff = dsu_w.diff(u, v);
29+
if (curr_diff == ll(1e18)) cout << -1 << '\n';
30+
else cout << (curr_diff % mod + mod) % mod << '\n';
31+
assert(dsu.size(u) == dsu_w.size(u));
32+
assert(dsu.size(v) == dsu_w.size(v));
33+
}
34+
}
35+
return 0;
36+
}

tests/scripts/compile_commented_snippets.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ git submodule update
2525
echo "vi rhs;"
2626
echo "vector<vi> mat;"
2727
echo "vector<vector<bool>> grid;"
28-
echo "int n,m,k,tl,tr,l,r,l1,r1,l2,r2,s_l,s_r,root_l,root_r,source,sink,total_flow,bccid,u,v,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2,len;"
28+
echo "int n,m,k,tl,tr,l,r,l1,r1,l2,r2,s_l,s_r,root_l,root_r,source,sink,total_flow,bccid,u,v,w,lsz,rsz,cols,cap,num,x,y,i,j,i1,i2,j1,j2,len;"
2929
} >entire_library_without_main
3030

3131
{

0 commit comments

Comments
 (0)