图论-二分图匹配-匈牙利算法

有关概念:

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

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

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

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

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

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

思路:

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

样例推导:

给出一幅二分图

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

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

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

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

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

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

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

至此找出极大增广路

邻接表

 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\n",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\n",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

时间: 2024-12-26 10:49:34

图论-二分图匹配-匈牙利算法的相关文章

USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)

The Perfect StallHal Burch Farmer John completed his new barn just last week, complete with all the latest milking technology. Unfortunately, due to engineering problems, all the stalls in the new barn are different. For the first week, Farmer John r

HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 49    Accepted Submission(s): 14 Problem Description There is a kindom of obsession, so people in this kingdom do things very

HDU1507 Uncle Tom&#39;s Inherited Land* 二分图匹配 匈牙利算法 黑白染色

原文链接http://www.cnblogs.com/zhouzhendong/p/8254062.html 题目传送门 - HDU1507 题意概括 有一个n*m的棋盘,有些点是废的. 现在让你用1*2的矩形覆盖所有的不废的点,并且不重叠,问最多可以覆盖多少个1*2的矩形,输出方案,有SPJ. 输入描述: 多组数据,每组首先两个数n,m(如果n和m为0,则结束程序) 然后给出k 然后给出k个二元组(x,y)表示废点的坐标. 题解 按照前两片博文的算法已经不行了,因为方案不对了. 所以我们要进行

矩阵游戏|ZJOI2007|BZOJ1059|codevs1433|luoguP1129|二分图匹配|匈牙利算法|Elena

1059: [ZJOI2007]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 162 MB Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏--矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两种操作:行交换操作:选择 矩阵的任意两行,交换这两行(即交换对应格子的颜色)列交换操作:选择矩阵的任意行列,交换这两列(即交换 对应格子的颜色)游戏的目标,即通过若干次操作,

网络流24题 第一题 - 洛谷2756 飞行员配对方案 二分图匹配 匈牙利算法

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 题意概括 裸的二分图匹配 题解 匈牙利算法 上板子 代码 #include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; const int N=100+5; int m,n,a,b,match[N

BZOJ 1191 [HNOI2006]超级英雄Hero:二分图匹配 匈牙利算法

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1191 题意: 有m道题,每答对一题才能接着回答下一个问题. 你一道题都不会,但是你有n个"锦囊妙计"(每个只能用一次). 对于每道题,你只能用该题规定的两种锦囊中的一种,来解决这道题. 问你最多能解决多少道题. 题解: 二分图最大匹配. 匈牙利算法. 问题与锦囊匹配. 最大匹配即为最多回答数. 但是题目中要求题目必须连续回答,不能中断. 所以在给每一个问题配对时,一旦匹配不上,

#图# #二分图匹配# #匈牙利算法#

二分图 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 区别二分图,关键是看点集是否能分成两个独立的点集. 二分图匹配(匈牙利算法) 最大匹配:设 是一个无向图.如顶点集V可分割为两个互不相交的子集 ,选择这样的子集中边数最大的子集称为图的最大匹配问题(maximal matching problem). 完全匹配:如果一个匹配中,  且

二分图匹配 匈牙利算法 hihocoder 1122

#1122 : 二分图二?二分图最大匹配之匈牙利算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了.因为过年时间并不是很长,所以姑姑希望能够尽可能在一天安排比较多的相亲.由于一个人同一天只能和一个人相亲,所以要从当前的相亲情况表里选择尽可能多的组合,且每个人不会出现两次.不知道有没有什么好办法,对于当前给定的相亲情况表,能够算出最多能同时安排多少组相亲呢? 同样的,我们先将给定的情况表转

【转】二分图匹配 匈牙利算法介绍

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-||暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在