二分图最大匹配

Hopcroft-Karp 算法,复杂度 O(E \sqrt{V})。

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

const int MAXN = 1005; // one side
const int MAXM = 1005; // the other side

namespace HopcroftKarp {
    std::vector<int> G[MAXN];
    int matx[MAXN], maty[MAXM], dx[MAXN], dy[MAXM];
    bool vis[MAXM];

    bool find(int u) {
        for (int v : G[u]) if (!vis[v] && dy[v] == dx[u] + 1) {
            vis[v] = true;
            if (!maty[v] || find(maty[v])) {
                matx[u] = v;
                maty[v] = u;
                return true;
            }
        }
        return false;
    }

    int solve(int n, int m) {
        std::fill(matx + 1, matx + n + 1, 0);
        std::fill(maty + 1, maty + m + 1, 0);
        int res = 0;
        while (true) {
            static std::queue<int> q;
            while (!q.empty()) q.pop();
            bool flag = false;
            std::fill(dx + 1, dx + n + 1, 0);
            std::fill(dy + 1, dy + m + 1, 0);
            for (int i = 1; i <= n; i++) if (!matx[i]) q.push(i);
            while (!q.empty()) {
                int u = q.front();
                q.pop();
                for (int v : G[u]) if (!dy[v]) {
                    dy[v] = dx[u] + 1;
                    if (maty[v]) {
                        dx[maty[v]] = dy[v] + 1;
                        q.push(maty[v]);
                    } else {
                        flag = true;
                    }
                }
            }
            if (!flag) break;
            std::fill(vis + 1, vis + m + 1, false);
            for (int i = 1; i <= n; i++) if (!matx[i] && find(i)) ++res;
        }
        return res;
    }
} // namespace HopcroftKarp

int main() {
    int n1, n2, m;
    scanf("%d %d %d", &n1, &n2, &m);
    for (int i = 0, u, v; i < m; i++) {
        scanf("%d %d", &u, &v);
        HopcroftKarp::G[u].push_back(v);
    }
    printf("%d\n", HopcroftKarp::solve(n1, n2));

    return 0;
}

results matching ""

    No results matching ""