GeneralMatching
Matching for general graphs. Fails with probability N / mod.
Time: O(N³) 40 lines not very well tested
Needs: "../numerical/MatrixInverse-mod.h"
content/graph/GeneralMatching.h ā Simon Lindholm, source: http://www.mimuw.edu.pl/~mucha/pub/mucha_sankowski_focs04.pdf
vector<pii> generalMatching(int N, vector<pii>& ed) {
vector<vector<ll>> mat(N, vector<ll>(N)), A;
for (pii pa : ed) {
int a = pa.first, b = pa.second, r = rand() % mod;
mat[a][b] = r, mat[b][a] = (mod - r) % mod;
}
int r = matInv(A = mat), M = 2*N - r, fi, fj;
assert(r % 2 == 0);
if (M != N) do {
mat.resize(M, vector<ll>(M));
rep(i,0,N) {
mat[i].resize(M);
rep(j,N,M) {
int r = rand() % mod;
mat[i][j] = r, mat[j][i] = (mod - r) % mod;
}
}
} while (matInv(A = mat) != M);
vi has(M, 1); vector<pii> ret;
rep(it,0,M/2) {
rep(i,0,M) if (has[i])
rep(j,i+1,M) if (A[i][j] && mat[i][j]) {
fi = i; fj = j; goto done;
} assert(0); done:
if (fj < N) ret.emplace_back(fi, fj);
has[fi] = has[fj] = 0;
rep(sw,0,2) {
ll a = modpow(A[fi][fj], mod-2);
rep(i,0,M) if (has[i] && A[i][fj]) {
ll b = A[i][fj] * a % mod;
rep(j,0,M) A[i][j] = (A[i][j] - A[fi][j] * b) % mod;
}
swap(fi,fj);
}
}
return ret;
}