匈牙利算法

匈牙利算法

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

#define ll long long
#define pb push_back
#define fi first
#define se second

const int N = 510;
vector<int > E[N];
int vis[N];
int girls[N];
int k, n, m;

//匈牙利算法
//复杂度O(VE),适合稀疏图
//每次先初始化 vis[]数组为0
//递归找增广路,可以理解为前面的人为后面的人腾位置

void init(){
    for(int i = 1; i <= n; ++i){
        E[i].clear();
        girls[i] = 0;
    }
}

bool find(int he){

    for(auto she : E[he]){
        //这个人没被访问
        if(!vis[she]){
            vis[she] = 1;
            //如果没有归属,  或者这个男生可以换一个女生
            if(!girls[she] || find(girls[she])){
                girls[she] = he;
                return true;
            }
            vis[she] = 0; //回溯
        }
    }

    return false;
}

void solve(){

    while(~scanf("%d", &k) && k){
        scanf("%d%d", &m, &n);
        init();

        int she, he;
        for(int i = 0; i < k; ++i){
            scanf("%d%d", &she, &he);
            E[he].pb(she);
        }

        int cnt = 0;
        for(int i = 1; i <= n; ++i){
            for(int x = 1; x <= m; ++x) vis[x] = 0;
            if(find(i)) ++cnt;
        }
        printf("%d\n", cnt);
    }
}

int main(){
    
    solve();    
    //cout << "not error" << endl;
    return 0;
}

 

posted @ 2020-05-29 22:21  SummerMingQAQ  阅读(184)  评论(0编辑  收藏  举报