zoukankan      html  css  js  c++  java
  • 二分图匹配之匈牙利算法

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

    匈牙利算法:

    我们将左边集合记为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;
    }
  • 相关阅读:
    Nginx平滑升级
    svn部署-linux
    svn服务备份与还原
    vmware exsi安装部署
    redis主从复制读写分离
    redis配置文件详解
    zabbix与agent端通信加密
    部署owa预览服务
    zabbix-3.4邮件报警
    centos7--zabbix3.4微信报警
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9737864.html
Copyright © 2011-2022 走看看