最近开始学习图论的二分匹配,关于最大匹配做一次小总结,希望自己后面回头来看一目明了,也对刚接触的人有帮助:

ps:开始有的文字很多....对于很多人来说一看到文字就烦啦...不过这个总结是针对匈牙利算法的总结,后面的匈牙利代码中有详细说明并结合图片说明,相信对刚接触的人会有帮助

个人觉得对于一个知识点最好是先知道这个”东东“是什么,然后在学习概念比较好,关于先知道是个什么“东东”--就是把这个知识点简单明了化,然后去了解其中令人头疼的概念!

关于二分匹配的最大匹配:

如果有G1、G2、G3三个女孩,B1。B2。B3三个男孩,有一天老师说要调整座位,就了解三个女孩的想法(想和哪一个男孩坐在一起----男孩的想法不考虑),G1说和三个男孩任何一个坐一起都喜欢,G2就说只想和B1坐一起,G3只想和 B2坐一起,那么老师改怎么安排座位,让尽可能多的女孩满意?这里就引入匹配:结合图形理解:

可以看到让G1和B3坐一起(配对/匹配)G2和B1一起,G3和B2一起,那么三个人都会满意,如果换成其他的方案,就不会是三个女孩都满意啦...那么这就是最大匹配

--------------------------------------------------------------------------------------------------------------------------------------------------------在大概了解了最大匹配是什么东东之后,就有必要了解一些概念啦,推荐:基本概念术语

下面是关于求最大匹配的匈牙利算法:

令G = (X,*,Y)是一个二分图,其中,X = {x1,x2,...xm}, Y = {y1,y2,...yn}。令M为G中的任一个匹配。
1)讲X的所有不与M的边关联的顶点标上(@),并称所有的顶点为未被扫描的。转到 2)。
2)如果在上一步没有新的标记加到X的顶点上,则停止。否则转到 3)。
3)当存在X被标记但未被扫描的顶点时,选择一个被标记但未被扫描的X的顶点,比如,xi,用(xi)标记Y的所有顶点,这些顶点被不属于M且尚未标记的边连到xi .现在,顶点xi是被扫描的。如果不存在被标记但未被扫描的顶点,则转到 4)。
4)如果在步骤 3)没有新的标记被标到Y的顶点上,则停止。否则,转到 5)。
5)当存在Y被标记但未被扫描的顶点时,选择Y的一个被标记但未被扫描的顶点,比如yi,用(yi)标记X的顶点,这些顶点被属于M且尚未标记的边连到yi.现在,顶点yi是被扫描的。如果不存在被标记但未被扫描的顶点,则转到 2)。
也可以叙述为:
[ZZ]匈牙利算法
关键在于匈牙利算法的递归过程中有很多重复计算的节点,而且这种重复无法避免,他不能向动态规划一样找到一个“序”将递归改为递推

下面结合hdu2063模板详细解释匈牙利算法:

题目和上面的座位匹配差不多

// 1216k 15ms
#include<stdio.h>
#include<string.h> #define MAX 501 int map[MAX][MAX];//map[i][j]=1表示i想和j一起,为0就是没有想一起的想法
int link[MAX];//link[i]=t就表示和i配对/匹配的是t!这里注意i表示是i号男生和t号女生配对
int useif[MAX];//useif[i]只有1和0两个值,表示i是不是当前考虑要匹配的,为1就是当前考虑i要匹配
//看了几个定义之后就从main函数中开始看
int n,m,k;

bool dfs(int t)
{
for(int i=1;i<=n;i++)//这里对于女孩t,考虑每一个男生能否和t匹配
{
if(!useif[i] && map[t][i])//i号男生没有被考虑,并且t想和i一起
{
useif[i]=1;//标记考虑
if(link[i] == -1 || dfs(link[i]))//如果i没有匹配的女生(link[i]=-1)或者--这个在开始有点难理解,后面给出一段话结合图片有助理解,这里只要明白这语句的意思是:if(t能和i匹配)
{
link[i]=t; return true;//能匹配就把link[i]更新为t,返回true
}
}
}
return false;
} int match()
{
int sum=0;
memset(link,-1,sizeof(link));//匹配之前,每个人(题目中是男孩)匹配为-1
for(int i=1;i<=m;i++)//这里,对于每一个女孩i,去选一个男孩匹配
{
memset(useif,0,sizeof(useif));//初始化对于女孩i,没有考虑任何男生
if(dfs(i))//看i能不能从男生中选一个匹配,调用dfs
sum++;//能匹配就产生一对啦....就加一
}
return sum;//返回能产生的对数
} int main()
{
while(scanf("%d",&k),k)
{
scanf("%d%d",&m,&n);
int i,j;
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
map[i][j]=0;//初始化都没有想法
int a,b;
for(i=0;i<k;i++)
{
scanf("%d%d",&a,&b);//对于每个a想和b一起就赋值map[a][b]=1
map[a][b]=1;
}
printf("%d\n",match());//开始match匹配,调用match
}
return 0;
}

这里对于上面的if加以说明:

拿案例来说(左边的是女生的标号,右边是等待女生选择的男生标号)

1   1
1    2

1   3

2   1

2   3

3   1

最开始我们用女孩一号去匹配得到如下图:

然后我们对于G2去选择,此时我们依旧从1号男生开始考虑,因为useif[1]在女孩2开始匹配的时候初始化为0啦,并且女孩2也想和男孩1匹配,就标记useif[1]为正在考虑,然后发现link[1]=1(也就是1号男生被1号女生选走啦)但是,确定是否2号女孩能和1号男孩匹配的还有一个条件,就是dfs(link[1]),意思是看能不能把和1号男生匹配的1号女生再去选择另一个男生配对,那么这个函数调用,我们的女1号就选择的2号男生,所以,这里的2号女生就可以和1号男生在一起啦...(有图有真相):

-----那么,后面就是一样的啦...

二分匹配之最大匹配学习总结完毕.......

[置顶] 白话二分匹配之最大匹配+附上hdu2063解题报告的更多相关文章

  1. [置顶] 白话最小边覆盖总结--附加 hdu1151结题报告

    刚开始看到这个题目的时候就觉得想法很明了,就是不知道如何去匹配... 去网上看了不少人的解题报告,但是对于刚接触“最小边覆盖”的我来说....还是很困难滴....于是自己又开始一如以往学习“最大独立集 ...

  2. 欧几里德&扩展以及求解线性方程学习总结--附上poj1061解题报告

    欧几里德算法: 欧几里德就是辗转相除法,调用这个gcd(a,b)这个函数求解a,b的最大公约数 公式: gcd(a,b)=gcd(b,a%b):并且gcd(a,b)=gcd(b,a)=gcd(-a,b ...

  3. UVALive - 7427 the math 【二分匹配】

    题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  5. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  6. [kuangbin带你飞]专题十 匹配问题 二分匹配部分

    刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...

  7. BZOJ 1189 二分匹配 || 最大流

    1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1155  Solved: 420[Submi ...

  8. Kingdom of Obsession---hdu5943(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943 题意:给你两个数n, s 然后让你判断是否存在(s+1, s+2, s+3, ... , s+n ...

  9. [ACM_图论] Sorting Slides(挑选幻灯片,二分匹配,中等)

    Description Professor Clumsey is going to give an important talk this afternoon. Unfortunately, he i ...

随机推荐

  1. Target runtime Apache Tomcat v6.0 is not defined. phyy Unknown Faceted Project Problem

    Description Resource Path Location TypeTarget runtime Apache Tomcat v6.0 is not defined. phyy Unknow ...

  2. jquery跳出当前的each循环

    break----用return false; continue --用return ture; jquery是对象链,所以$(..).each()返回的还是对象集合.each(function(){ ...

  3. Mounting File Systems

    1.Mounting File Systems Just creating a partition and putting a file system on it is not enough to s ...

  4. SoundPool 音频播放 详解 示例

    简介 如果应用程序经常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.因为MediaPlayer存在如下缺点: 1) 延时时间较长,且资源占用率高. 2) ...

  5. [JavaScript]plupload多图片上传图片

    var uploader = new plupload.Uploader({ //创建实例的构造方法     runtimes: 'html5,flash,silverlight,html4',    ...

  6. ASP.NET协作应用集成到trsids身份验证服务器的开发流程

    开发Actor协同模块: (参考TRSIDS4.0 协作应用集成手册[asp.net]) ASP.Net协作应用集成到IDS之前,需要开发Actor类实现协作应用回调接口中定义的本地登录.退出.用户信 ...

  7. 几种常用的Java数据源解决方案

    http://blog.163.com/qqabc20082006@126/blog/static/22928525201041944847653/

  8. JavaScript 客户端JavaScript之样式表操作(DOM API 提供模块之一)

    层叠样式 表和动态HTML   层叠样式表(CSS)是指定HTML文档或XML文档的表现的标准.     使用CSS和Javascript,可以创建出各种视觉效果,这些效果可以统称为动态HTML(DH ...

  9. pydev出现Project interpreter not specified(eclipse+pydev)

    出现上述错误的原因是因为没有为Pydev指定python.exe位置 修改步骤依次是 1.从Eclipse的菜单 Window --> Preferences 打开首选项配置:       2. ...

  10. ios 实时刷新屏幕

    index=; // timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:layer selector:@selector(setNe ...