MCPcopy Create free account
hub / github.com/SuprDewd/CompetitiveProgramming / MatroidIntersection

Class MatroidIntersection

code/other/matroid_intersection.cpp:1–37  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1struct MatroidIntersection {
2 virtual void add(int element) = 0;
3 virtual void remove(int element) = 0;
4 virtual bool valid1(int element) = 0;
5 virtual bool valid2(int element) = 0;
6 int n, found; vi arr; vector<ll> ws; ll weight;
7 MatroidIntersection(vector<ll> weights)
8 : n(weights.size()), found(0), ws(weights), weight(0) {
9 rep(i,0,n) arr.push_back(i); }
10 bool increase() {
11 vector<tuple<int,int,ll>> es;
12 vector<pair<ll,int>> d(n+1, {1000000000000000000LL,0});
13 vi p(n+1,-1), a, r; bool ch;
14 rep(at,found,n) {
15 if (valid1(arr[at])) d[p[at] = at] = {-ws[arr[at]],0};
16 if (valid2(arr[at])) es.emplace_back(at, n, 0); }
17 rep(cur,0,found) {
18 remove(arr[cur]);
19 rep(nxt,found,n) {
20 if (valid1(arr[nxt]))
21 es.emplace_back(cur, nxt, -ws[arr[nxt]]);
22 if (valid2(arr[nxt]))
23 es.emplace_back(nxt, cur, ws[arr[cur]]); }
24 add(arr[cur]); }
25 do { ch = false;
26 for (auto [u,v,c] : es) {
27 pair<ll,int> nd(d[u].first + c, d[u].second + 1);
28 if (p[u] != -1 && nd < d[v])
29 d[v] = nd, p[v] = u, ch = true; } } while (ch);
30 if (p[n] == -1) return false;
31 int cur = p[n];
32 while(p[cur]!=cur)a.push_back(cur),a.swap(r),cur=p[cur];
33 a.push_back(cur);
34 sort(a.begin(), a.end()); sort(r.rbegin(), r.rend());
35 iter(it,r)remove(arr[*it]),swap(arr[--found],arr[*it]);
36 iter(it,a)add(arr[*it]),swap(arr[found++],arr[*it]);
37 weight -= d[n].first; return true; } };
38// vim: cc=60 ts=2 sts=2 sw=2:

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected