[矩阵][高斯消元][二分图]Codeforces 736D.Permutations

5 篇文章 0 订阅
3 篇文章 0 订阅

Description

给定一个二分图。
已知这个二分图的完备匹配的个数是奇数。
询问删除每条边后完备匹配个数是奇数还是偶数。

Solution

一个二分图的完备匹配个数就是该图邻接矩阵的积和式。
而且在膜 2 意义下积和式的值与行列式相等。
矩阵的行列式,伴随矩阵,逆之间有这样的关系

A=|A|A1
因为伴随矩阵就是

Ai,j=Mj,i
并且 |A| 为奇数,所以其实在膜 2 意义下,A=A1
答案是
|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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值