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

    有关概念:

      二分图:图G中的点集可以分为两个互不相交的子集,且G中的每条边连接的两个点分别属于这两个子集

      二分图匹配:二分图G的子图M中每个结点上只连一条边,则称M为一个匹配

      极大匹配:无法再向二分图中加边且满足匹配条件的匹配

      最大匹配:所有极大匹配中边数最多的一个

      增广路:若P为图G上连接两个未匹配结点的路径,且已匹配边和未匹配边在P上交替出现,则称P为相对于M的一条增广路

      匈牙利算法即用来求二分图的极大匹配

    思路:

      在图G中找出增广路P,对P上每一条边取反(即已匹配边改为未匹配边,未匹配边改为已匹配边),重复直到找不到增广路为止

    样例推导:

    给出一幅二分图

    从X1开始,搜到X1-Y1,成增广路,连接X1-Y1

    [ATTENTION]从X2开始,搜到X2-Y1-X1-Y3,成增广路

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    [ATTENTION] 取消连接X1-Y1,连接X1-Y3,X2-Y1

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    从X3开始,搜到X3-Y1-X2,不通,不作更改

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    搜到X3-Y2,成增广路,连接X3-Y2

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    从X4开始,搜到X4-Y3-X1-Y1-X2,不通,不作更改

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    搜到X4-Y4,成增广路,连接X4-Y4

    图论-二分图匹配-匈牙利算法 - xqmmcqs - xqmmcqs的博客

    至此找出极大增广路

    邻接表

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 
     4 int n,m,cnt,match[MAXN],head[MAXN],ans;
     5 bool check[MAXN];
     6 struct node
     7 {
     8     int v,next;
     9 }edge[MAXN*5];
    10 void add(int x,int y)
    11 {
    12     edge[++cnt].next=head[x];
    13     head[x]=cnt;
    14     edge[cnt].v=y;
    15 }
    16 bool Hungary(int u)
    17 {
    18     for(int i=head[u];i;i=edge[i].next)
    19     {
    20         int v=edge[i].v;
    21         if(!check[v])//判断v是否在增广路中
    22         {
    23             check[v]=true;
    24             if(!match[v]||Hungary(match[v]))
    25             {
    26                 match[v]=u;//v对应u
    27                 return true;
    28             }
    29         }
    30     }
    31     return false;
    32 }
    33 int main()
    34 {
    35     //省略输入 
    36     for(int i=1;i<=n;i++)
    37     {
    38         if(!match[i])
    39         {
    40             memset(check,false,sizeof(check));
    41             if(Hungary(i))ans++;
    42         }
    43     }
    44     printf("%d
    ",ans);
    45     return 0;
    46 }

    邻接矩阵

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 
     4 int n,m,cnt,match[MAXN],map[MAXN][MAXN],ans;
     5 bool check[MAXN];
     6 bool Hungary(int u)
     7 {
     8     for(int i=1;i<=n;i++)
     9     {
    10         if(!check[i]&&map[u][i])
    11         {
    12             check[i]=true;
    13             if(!match[i]||Hungary(match[i]))
    14             {
    15                 match[i]=u;
    16                 return true;
    17             }
    18         }
    19     }
    20     return false;
    21 }
    22 int main()
    23 {
    24     //省略输入 
    25     for(int i=1;i<=n;i++)
    26     {
    27         if(!match[i])
    28         {
    29             memset(check,false,sizeof(check));
    30             if(Hungary(i))ans++;
    31         }
    32     }
    33     printf("%d
    ",ans);
    34     return 0;
    35 }

    *参考:https://www.byvoid.com/blog/hungary/

    http://baike.baidu.com/view/501081.htm

    http://baike.baidu.com/link?url=QbNL6DpNwvt1u3Yka7I-xy9Ymig1HNZid4j2MGsDxlyzCOXcdhjkG8sSJvBtK2zkZzOU007ooiSiujjwOpYCMq

    http://baike.baidu.com/link?url=YStVW2tIYiH6flGjr0VqIu44uM9Vhckq8pyKLpt651sGYpOFHsGI3TL9d2T5Tmy84QXmt__mVc0zerNUBfeecK

  • 相关阅读:
    Java学习62
    Java学习61
    Maven3种打包方式之一maven-assembly-plugin的使用
    sftp 上传下载 命令介绍
    JMock+Junit4结合完成TDD实例
    UML类图中类与类的四种关系图解
    接口之间的多继承
    Linux中在当前目录下查找某个文件
    .gitignore与exclude
    pro git
  • 原文地址:https://www.cnblogs.com/xqmmcqs/p/5965702.html
Copyright © 2011-2022 走看看