Description
给定一个二分图。
已知这个二分图的完备匹配的个数是奇数。
询问删除每条边后完备匹配个数是奇数还是偶数。
Solution
一个二分图的完备匹配个数就是该图邻接矩阵的积和式。
而且在膜
2
意义下积和式的值与行列式相等。
矩阵的行列式,伴随矩阵,逆之间有这样的关系
A∗i,j=Mj,i
并且
|A|
为奇数,所以其实在膜
2
意义下,答案是
|A| xor Mv,u
直接
GaussJordan
求个逆就好啦。
可以 bitset 优化哦。。
#include <bits/stdc++.h>
using namespace std;
const int M = 505050;
const int N = 2020;
const int INF = 1 << 30;
inline char get(void) {
static char buf[100000], *S = buf, *T = buf;
if (S == T) {
T = (S = buf) + fread(buf, 1, 100000, stdin);
if (S == T) return EOF;
}
return *S++;
}
template<typename T>
inline void read(T &x) {
static char c; x = 0; int sgn = 0;
for (c = get(); c < '0' || c > '9'; c = get()) if (c == '-') sgn = 1;
for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';
if (sgn) x = -x;
}
bitset<N> A[N], iA[N];
int n, q, pos, det;
int u[M], v[M];
int main(void) {
freopen("1.in", "r", stdin);
read(n); read(q);
for (int i = 0; i < q; i++) {
read(u[i]); read(v[i]);
A[u[i]][v[i]] = 1;
}
for (int i = 1; i <= n; i++)
iA[i][i] = 1;
for (int i = 1; i <= n; i++) {
pos = i;
for (int j = i + 1; j <= n; j++)
if (A[j][i]) pos = j;
swap(A[i], A[pos]);
swap(iA[i], iA[pos]);
for (int j = 1; j <= n; j++)
if (j != i && A[j][i]) {
A[j] ^= A[i];
iA[j] ^= iA[i];
}
}
for (int i = 0; i < q; i++)
if (iA[v[i]][u[i]]) puts("NO");
else puts("YES");
return 0;
}