AcWing 861. 二分图的最大匹配(HK算法)

#include

#define IOS ios::sync_with_stdio(false);cin.tie(nullptr)
#define endl "\n"
#define xx first
#define yy second

using namespace std;

const int N = 5e4 + 5, M = 6e5+ 5;
const int inf = 0x3f3f3f3f;

struct Edge
{
    int to, next;
}ns[M];
 
bool isnp[M], vst[N];;
int n, cur, dis;
int Mx[N], My[N], Nx, Ny, dx[N], dy[N], Ax[N], Ay[N];
int head[N], ext[M];

 
bool searchP()
{
    queue<int> Q;
    dis = inf;
    memset(dx, -1, sizeof dx);
    memset(dy, -1, sizeof dy);
    for (int i = 1; i <= Nx; ++i)
    {
        if (Mx[i] == -1)
        {
            Q.push(i);
            dx[i] = 0;
        }
    }
    while (!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        if (dx[u] > dis) break;
        for (int i = head[u]; i != -1; i = ns[i].next)
        {
            int v = ns[i].to;
            if (dy[v] == -1)
            {
                dy[v] = dx[u] + 1;
                if (My[v] == -1) dis = dy[v];
                else
                {
                    dx[My[v]] = dy[v] + 1;
                    Q.push(My[v]);
                }
            }
        }
    }
    return dis != inf;
}
 
bool DFS(int u)
{
    for (int i = head[u]; i != -1; i = ns[i].next)
    {
        int v = ns[i].to;
        if (!vst[v] && dy[v] == dx[u] + 1)
        {
            vst[v] = 1;
            if (My[v] != -1 && dy[v] == dis) continue;
            if (My[v] == -1 || DFS(My[v]))
            {
                My[v] = u;
                Mx[u] = v;
                return true;
            }
        }
    }
    return false;
}
 
int Match()
{
    int res = 0;
    memset(Mx, -1, sizeof Mx);
    memset(My, -1, sizeof My);
    while (true)
    {
        memset(vst, 0 , sizeof vst);
        queue<int> Q;
        dis = inf;
        memset(dx, -1, sizeof dx);
        memset(dy, -1, sizeof dy);
        for (int i = 1; i <= Nx; ++i)
        {
            if (Mx[i] == -1)
            {
                Q.push(i);
                dx[i] = 0;
            }
        }
        while (!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            if (dx[u] > dis) break;
            for (int i = head[u]; i != -1; i = ns[i].next)
            {
                int v = ns[i].to;
                if (dy[v] == -1)
                {
                    dy[v] = dx[u] + 1;
                    if (My[v] == -1) dis = dy[v];
                    else
                    {
                        dx[My[v]] = dy[v] + 1;
                        Q.push(My[v]);
                    }
                }
            }
        }
        if (dis == inf) break;
        for (int i = 1; i <= Nx; ++i)
        {
            if (Mx[i] == -1 && DFS(i))
                ++res;
        }
    }
    return res;
}
 
void add_edge(int u, int v)
{
    ns[cur].next = head[u];
    ns[cur].to = v;
    head[u] = cur;
    ++cur;
}

void solve()
{
    cur = 0;
    memset(head, -1, sizeof head);
    memset(ext, 0, sizeof ext);
    Nx = Ny = 0;
    int n1, n2, m;
    cin >> n1 >> n2 >> m;
    map<int, int> mpx, mpy;
    for(int i = 1; i <= m; i ++)
    {
        int x, y;
        cin >> x >> y;
        if(!mpx[x])
        {
            Ax[++Nx] = x;
            ext[x] = Nx;
            mpx[x] = Nx;
        }
        if(!mpy[y])
        {
            Ay[++Ny] = y;
            ext[y] = Ny;
            mpy[y] = Ny;
        }

        add_edge(mpx[x], mpy[y]);
    }
    cout << Match() << endl;
}

signed main()
{
    solve();
    return 0;
}

你可能感兴趣的:(图论,算法)