zoukankan      html  css  js  c++  java
  • 二分图匹配(匈牙利算法模板)

    一、最大匹配——匈牙利算法

    /****************************************************
    二分图匹配(匈牙利算法的DFS实现)
    INIT:g[][]两边定点划分的情况
    CALL:res=hungary();输出最大匹配数
    优点:适于稠密图,DFS找增广路快,实现简洁易于理解
    时间复杂度:O(VE);
    ***************************************************
    */
    const int MAXN=1000;
    int uN,vN; //u,v数目
    int g[MAXN][MAXN];//编号是0~n-1的
    int linker[MAXN];
    bool used[MAXN];
    bool dfs(int u)
    {
    int v;
    for(v=0;v<vN;v++)
    if(g[u][v]&&!used[v])
    {
    used[v]
    =true;
    if(linker[v]==-1||dfs(linker[v]))
    {
    linker[v]
    =u;
    return true;
    }
    }
    return false;
    }
    int hungary()
    {
    int res=0;
    int u;
    memset(linker,
    -1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
    memset(used,
    0,sizeof(used));
    if(dfs(u)) res++;
    }
    return res;
    }

    简单例子:

    HDU 2063过山车

    #include<stdio.h>

    #include<string.h>

    const int MAXN=510;

    int uN,vN;  //u,v数目

    int g[MAXN][MAXN];//编号是0~n-1

    int linker[MAXN];

    bool used[MAXN];

    bool dfs(int u)

    {

        int v;

        for(v=1;v<=vN;v++)

            if(g[u][v]&&!used[v])

            {

                used[v]=true;

                if(linker[v]==-1||dfs(linker[v]))

                {

                    linker[v]=u;

                    return true;

                }   

            } 

        return false; 

    }   

    int hungary()

    {

        int res=0;

        int u;

        memset(linker,-1,sizeof(linker));

        for(u=1;u<=uN;u++)

        {

            memset(used,0,sizeof(used));

            if(dfs(u))  res++;

        }

        return res;  

    } 

    int main()

    {

        int k;

        int u,v;

        while(scanf("%d",&k),k)

        {

            scanf("%d%d",&uN,&vN);

            memset(g,0,sizeof(g));

            while(k--)

            {

                scanf("%d%d",&u,&v);

                g[u][v]=1;

            }

            printf("%d\n",hungary());  

        } 

        return 0; 

    } 

     

    例:HDU 1045 Fire Net

    /*

    HDU 1045

    */

    #include<stdio.h>

    #include<string.h>

    #include<iostream>

    using namespace std;

    int uN,vN;

    int g[20][20];

    int linker[20];

    bool used[20];

    char map[5][5];

    int mapr[5][5];

    int mapl[5][5];

    bool dfs(int u)

    {

        int v;

        for(v=1;v<=vN;v++)

            if(g[u][v]&&!used[v])

            {

                used[v]=true;

                if(linker[v]==-1||dfs(linker[v]))

                {

                    linker[v]=u;

                    return true;

                }   

            }

        return false;  

    } 

    int hungary()

    {

        int res=0;

        int u;

        memset(linker,-1,sizeof(linker));

        for(u=1;u<=uN;u++)

        {

            memset(used,0,sizeof(used));

            if(dfs(u))  res++;

        }  

        return res;

    } 

    int main()

    {

        int i,j,n;

        while(scanf("%d",&n),n)

        {

            memset(mapl,0,sizeof(mapl));

            memset(mapr,0,sizeof(mapr));

            memset(g,0,sizeof(g));

            for(i=1;i<=n;i++)

               for(j=1;j<=n;j++)

               {

                   cin>>map[i][j];

                   if(map[i][j]=='X')

                      mapl[i][j]=mapr[i][j]=-1;

               } 

               int p1=0;

               uN=0;vN=0;

               //给行编号

               for(i=1;i<=n;i++)

                  for(j=1;j<=n;j++)

                  {

                      while(mapr[i][j]==-1&&j<=n)

                          j++;

                      p1++;

                      while(mapr[i][j]!=-1&&j<=n)

                      {

                          mapr[i][j]=p1;

                          if(uN<p1)  uN=p1;

                          j++;

                      }   

                  }

              int p2=0;

              //给列编号

              for(j=1;j<=n;j++)

                 for(i=1;i<=n;i++)

                 {

                     while(mapl[i][j]==-1&&i<=n)

                          i++;

                      p2++;

                      while(mapl[i][j]!=-1&&i<=n)

                      {

                          mapl[i][j]=p2;

                          if(vN<p2)  vN=p2;

                          i++;

                      }   

                 }

             //建图

             for(i=1;i<=n;i++)

                for(j=1;j<=n;j++)

                {

                    if(mapr[i][j]!=-1&&mapl[i][j]!=-1)

                      g[mapr[i][j]][mapl[i][j]]=1;

                }

             printf("%d\n",hungary());           

        }

        return 0;   

    }

  • 相关阅读:
    PSR
    php类与对象
    二进制、位运算及其用处
    安装LNMP笔记
    计算机基础
    Python3编写HFS(CVE2014-6287)检测脚本
    windows和iis对应版本关系
    phpStudy8.1.0.1配置子域名多网站
    Xml外部实体注入
    xss小游戏通关-全答案
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2132828.html
Copyright © 2011-2022 走看看