• 匈牙利算法


    二分图最大匹配

    邻接表:O(nm)

    struct node{
        int s,t,nxt ; 
    }e[1005] ;
    int k,m,n,head[505],cnt,match[505],vis[505] ;
    int find(int s)
    {
        for(int i=head[s] ;i!=-1 ;i=e[i].nxt)
        {
            int tt=e[i].t ;
            if(!vis[tt])
            {
                vis[tt]=1 ;
                if(match[tt]==-1 || find(match[tt]))
                {
                    match[tt]=s ;
                    return 1 ;
                }
            }
        }
        return 0 ;
    }
    int max_match()
    {
        int ans=0 ;
        memset(match,-1,sizeof(match)) ;
        for(int i=1 ;i<=m ;i++)
        {
            memset(vis,0,sizeof(vis)) ;
            ans+=find(i);
        }
        return ans;
    }
    void add(int s,int t) {e[cnt].s=s ;e[cnt].t=t ;e[cnt].nxt=head[s] ;head[s]=cnt++ ;}
    void read_graph()
    {
        memset(head,-1,sizeof(head)) ;
        cnt=0 ;
        for(int i=0 ;i<k ;i++)
        {
            int s,t ;
            scanf("%d%d",&s,&t) ;
            add(s,t) ;
        }
    }
    View Code

    邻接矩阵:O(n^3) 可记录每个点匹配的情况,使用前M数组要清0

    int T,M[105][105],n,m,linkx[105],linky[105],vis[105] ;
    int find(int s)
    {
        for(int i=1 ;i<=m ;i++)
        {
            if(M[s][i])
            {
                if(vis[i]==T)continue ;
                vis[i]=T ;
                if(!linky[i] || find(linky[i]))
                {
                    linky[i]=s ;
                    linkx[s]=i ;
                    return 1 ;
                }
            }
        }
        return 0 ;
    }
    int max_match()
    {
        int ans=0 ;
        memset(linkx,0,sizeof(linkx)) ;
        memset(linky,0,sizeof(linky)) ;
        memset(vis,0,sizeof(vis)) ;
        for(int i=1 ;i<=n ;i++)
        {
            T=i ;
            ans+=find(i);
        }
        return ans;
    }
    View Code

    其他应用:

    1、二分图的最小顶点覆盖数(在二分图中求最少的点,让每条边至少和其中一个点关联)==二分图的最大匹配数

    证明见konig定理:http://baike.baidu.com/link?url=CEpX8XOz1PW7Z0bdkqIPRU1RlhYDrD26iYGN347jze8ak_ERxrWLR-jC6kPQH-1QVOuT0_0GqMyAKFURFnTRSq

    2、DAG图的最小路径覆盖数(用尽量少的不相交简单路径覆盖有向无环图(DAG)G的所有顶点)==节点数-最大匹配数

    按上面方式构图,证明不会

    3、二分图最大独立集数==节点数-最大匹配数

    构图如上,证明不会

  • 相关阅读:
    Power Strings P5019
    Floyd模板题 P1704
    【训练题】强连通分量缩点 P1679
    字符串hash模板题 P5018
    Dijkstra模板题 P1710
    【训练题】分队 P1672
    二分图模板题 P1631
    【训练题】无序字母对 P1675
    KMP模板题 P1537
    马路 树链剖分/线段树/最近公共祖先(LCA)
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3653686.html
Copyright © 2020-2023  润新知