码迷,mamicode.com
首页 > 编程语言 > 详细

二分图匹配之匈牙利算法

时间:2018-10-02 22:30:47      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:算法   cst   include   max   cstring   set   ios   size   color   

二分图匹配的问题都可以用网络流来做,但是二分图匹配的一些思想还是得了解一下。

匈牙利算法:

我们将左边集合记为S,右边集合记为T,

加边的时候只需要加S---->T的边,后面会提到原因。

我们枚举点进行增广,增广的时候只访问当次增广没有访问到的点。

什么情况下才算是成功的增广?

u---->v的v点没有匹配过,或者当前匹配v的点还能找到一个点去匹配,

这样u就与v匹配。并且每次枚举点,就要清空vis数组,因为我们不希望

在一次增广中重复访问访问过的结点。

∞reason:每一次成功的增广都只需要从S集合中在T集合中找匹配,

继续用记录v有没有被匹配,每次都会从u去找匹配。

代码:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#define ll long long int
using namespace std;
const int N=1e6+5;
int n,m,ee,num=1,ans;
int cx[N],cy[N],vis[N],head[N];
struct E{
    int nxt,to;
}e[N];
void add(int u,int v){
    e[++num].to=v;
    e[num].nxt=head[u];
    head[u]=num;
}
int dfs(int u){
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].to;
        if(!vis[v]){
        vis[v]=1;
        if((!cy[v])||(dfs(cy[v]))){
            cy[v]=u;
            return 1;
        }
        }
    }
    return 0;
}
void max_match(){
    for(int u=1;u<=n;u++){
    memset(vis,0,sizeof(vis));
    ans+=dfs(u);
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&ee);
    for(int i=1;i<=ee;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        if(u<=n&&v<=m)
        add(u,v);
    }
    max_match();
    printf("%d",ans);
    return 0;
}

 

二分图匹配之匈牙利算法

标签:算法   cst   include   max   cstring   set   ios   size   color   

原文地址:https://www.cnblogs.com/sky-zxz/p/9737864.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!