一、二分图匹配

给出一张二分图,请求出最大匹配数量

匈牙利算法:

让左边的与右边的

 

#include <bits/stdc++.h>
#define maxn 1005
#define icn cin 
#define itn int
using namespace std;
//左边的每个人都尝试去和右边的人匹配 
bool z[maxn][maxn];//z[i][j] 代表左边第i个点和右边第j个点能不能匹配 
int dist[maxn];
int n,m;
bool vis[maxn]; //vis[i] 代表右边第i个点在这一轮中有没有被请求匹配 
//左边有n 个点 右边有m个点
int k;//边数 
long long ans = 0; 
int reault[maxn];//result[i] 代表右边第i个点和左边第result[i]个点匹配 
bool dfs(int i){//让左边第i个点尝试  
    for(int j = 1; j <= m; j++)//让左边额第i个点和右边的第j个点尝试匹配
        if(z[i][j] && !vis[j]){
            vis[j] = true;//有点匹配 
            if(!result[j] || dfs(result[j])){
                result[j] = i;
                return true;
            }
        }
    return false;
}
int main(){
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for(int i = 1; i <= k; i++){
        int p1,p2;
        cin >> p1 >> p2;
        z[p1][p2] = true;
    }
    for(int i = 1; i <= n; i++){
        memset(vis,false,sizeof(vis));
        if(dfs(i)) ans ++;
    }
    cout << ans << '\n';
    return 0;
    //O(n^3) 
}

 

优化:

#include<bits/stdc++.h>
#define ll long long
#define itn int

using namespace std;

const int maxn=1005;
int n,m,k;
int ans;
vector<int> z[maxn];
//z[i][j]代表左边第i个点第j个条边连向谁 
//n代表左边有n个点
//m代表右边有m个点 
bool vis[maxn];
//vis[i]代表右边第i个点在这一轮中有没有被请求匹配
int result[maxn];
//result[i] 代表右边第i个点和左边第result[i]个点匹配 

void add_edge(int p1,int p2)
{
    z[p1].push_back(p2);
}

inline bool dfs(int i)
{
    //让左边第i个点尝试匹配
    //返回是否匹配成功
    for(int k=0;k<z[i].size();k++)
    {
        //让左边第i个点和右边第j个点匹配 
        int j=z[i][k];
        if(!vis[j])
        {
            vis[j]=true;
            if(!result[j]||dfs(result[j]))
            {
                //右边这个点j没有和任何点匹配
                result[j]=i;
                return true; 
            }
        }
    }
    return false;
    //枚举所有点都不可行 
}

int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=k;i++)
    {
        int p1,p2;
        cin>>p1>>p2;
        add_edge(p1,p2);
    }
    for(int i=1;i<=n;i++)
    {
        memset(vis,false,sizeof(vis));
        if(dfs(i)) ans++;//左边第i个点匹配成功,增加答案数量 
    }
    cout<<ans;
    return 0;
}
 

 

posted on 2023-07-13 11:28  Slz_konnyaku  阅读(52)  评论(0)    收藏  举报