acwing 861 Maximum matching of bipartite graphs (Hungarian algorithm)

Topic

Insert picture description here

answer

  1. Hungarian algorithm:Find the maximum number of matches of a bipartite graph, O(nm), which is actually much smaller than this time complexity, and follows the principle of "first come first serve, let you let"

Insert picture description here
2. Simulation process: 1 matches the first 6, 2 matches the first 7, and 3 has only one 6 that can match, but 6 has matched 1, we need to see whether the point 1 matched by 6 can match other points Point, found that 1 can match 8, in addition to matching 6, so let 1 match 8, 3 match 6, 4 match 7.

Code

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 1e5 + 10;


int n1, n2, m;
int h[N], e[N], ne[N], idx;
int match[N];  //存储每个点当前匹配的点
bool st[N];    //表示每个点是否已经被遍历过

void add(int a, int b) {
    
    
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}

bool find(int x) {
    
    

    for (int i = h[x]; i != -1; i=ne[i]) {
    
    
        int j = e[i];
        if (!st[j]) {
    
    
            st[j] = true;
            //如果这个点没有被匹配或者是这个点所匹配的点能找到别的点
            if(match[j]==0||find(match[j])){
    
    
                match[j]=x;
                return true;
            }
        }
    }
    return false;
}

int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    memset(h, -1, sizeof h);

    cin >> n1 >> n2 >> m;

    for (int i = 1; i <= m; i++) {
    
    
        int a, b;
        cin >> a >> b;
        add(a, b);
    }

    int res = 0;
    for (int i = 1; i <= n1; i++) {
    
    
        memset(st, false, sizeof st);
        if (find(i)) res++;
    }

    cout<<res<<endl;

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_44791484/article/details/114578300