匈牙利算法

(一)首先明确匈牙利算法是干嘛滴?

    匈牙利算法是解决二部图最大匹配问题滴。

(二)算法的核心思想:不断寻找增广路径,每找到一条增广路径,就通过异或操作使匹配边数加一,直到找不到增广路径,算法结束。

(三)算法的基本步骤:

    (1)任取二部图G(X,Y)的匹配M,若M饱和X,则停止。若M不能饱和X,则取X的未标记的M非饱和点x。(标记的点表示经过此点不存在增广路)令S={x},T= ?.(T集合中的点表示N(S)中已经加入增广路的点)(当不存非饱和点或者所有非饱和点都被标记,算法结束)

    (2)若N(S)=T,(S集合中的所有点的对应项都是已经走过的的点)则返回(1),即无经过x的增广通路,标记x。否则,取y ∈N(S)-T。

    (3)若y是M饱和的,则存在z ∈X-S使yz ∈M.令S=S∪{z},T=T∪{y},转入(2)。若y是M非饱和的,则G中存在以x为起点y为终点的M增广通路P。用令M=M异或EP,即将这条增广路上的已匹配边与未匹配边对换,得到比原来匹配数多一的新匹配,转入(1).

(四)算法的核心结构

 1 void hungary()//匈牙利算法
 2 {
 3     for i->1 to n
 4         if (从i的对应项出有可增广路)
 5             匹配数++;
 6     输出 匹配数;
 7 }
 8 bool  findpath(k)//寻找从k出发的对应项出的可增广路
 9 {
10     while (从邻接表中列举k能关联到顶点j){
11         if (j不在增广路上){
12             把j加入增广路;
13             if (j是未匹配点 或者 从j的对应项出发有可增广路)
14                 修改j的对应项为k;//也就是说边(k,j)匹配,j对应匹配到k上
15                 则从k的对应项出有可增广路,返回true;
16             }
17         }
18     }
19     则从k的对应项出没有可增广路,返回false;
20 }

(五)算法的核心代码

 1 bool findpath(int x)
 2 {
 3     visx[x] = true;
 4     for(int y = 1 ; y <= ny ; ++y){
 5         if(!visy[y] && (lx[x] + ly[y] == G[x][y])){
 6             visy[y] = true;
 7             if(match[y] == -1 || findpath(match[y])){
 8                 match[y] = x;
 9                 return true;
10             }
11         }
12     }
13     return false;
14 }

今天刚学完匈牙利算法,趁热打铁,赶快写篇博客加深一下印象!看不懂你打我!!!不认真看打死你!!!

时间: 2024-12-30 22:57:11

匈牙利算法的相关文章

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

【codevs】1022覆盖(匈牙利算法)

嗯,先上题目描述... 此题接近裸的匈牙利算法,将陆地和其四周是陆地的点连一条边,这样就有了一个无向图. 接着就是从第一个点出发枚举未被标记的点,标记与其对应的另一个点(因为是1*2的长方形). 开了一个四维数组e[x1][y1][x2][y2],若为零代表点(x1,y1)与(x2,y2)不连通. match[x1][y1][1]放与点(x1,y1)配对的另一个点的x,match[x1][y1][2]放与点(x1,y1)配对点的y. 还有就是更改的时候记得双向更改,因为是无向图啊. 然后就跑df

FOJ 2232 匈牙利算法找二分图最大匹配

题目链接 简单理解匈牙利算法 简单理解二分图 尽量让每一个随从击败一个对手且随从全部存活,关键是为每一个随从找对手(递归过程),"腾". #include<iostream> #include<cstdio> #include<cstring> using namespace std; int used[110]; int g[110][110]; //建立随从和对手的对战关系 int ee[110]; int n; struct people{ i

匈牙利算法——S.B.S.

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

UVALive5874 - Social Holidaying-二分图匹配/匈牙利算法

有n个家庭,m个房间,一个房间只能两个家庭住.求最大匹配. 比较标准的二分图问题.先初始化把可能的家庭建边,然后跑一边匈牙利算法. 最后的答案是最大匹配数/2,因为建图时有重复. #include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; const int MAXN = 410; int uN,vN; int g[MAXN][MA

棋盘覆盖及匈牙利算法

题目描述 Description 给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖. 输入描述 Input Description 第一行为n,m(表示有m个删除的格子)第二行到m+1行为x,y,分别表示删除格子所在的位置x为第x行y为第y列 输出描述 Output Description 一个数,即最大覆盖格数 样例输入 Sample Input 8 0 样例输出 Sample Output 32 数据范围及提示 Data Size &am

数学:匈牙利算法

匈牙利算法:它由匈牙利数学家Edmonds于1965年提出,因而得名.此算法的核心就是寻找增广路径,通过增广路径来求二分图最大匹配的一种算法. 通过这个图片来讲述一下.黑色代表A\B\C\D四只小狗,红色代表四种口味的骨头,每一条线表示的是小狗喜欢吃这个口味的骨头. 我们按照顺序给小狗们分配骨头,先给A分配,很明显a无人占用并且小A狗很喜欢,分配,博主最喜欢成人之美.(????) 现在给小B狗分配,小B喜欢b,前提b无人占用并且小B心仪很久,又成全一只小狗,哇哈哈~~ 轮到小C狗了,小C等了好久

poj1274 匈牙利算法 二分图最大匹配

poj1274 题意: 有n个奶牛, m个畜舍, 每个畜舍最多装1头牛,每只奶牛只有在自己喜欢的畜舍里才能产奶. 求最大产奶量. 分析: 其实题意很明显, 二分图的最大匹配, 匈牙利算法. #include<iostream> #include<cstdio> #include<string.h> #include<cstring> using namespace std; int n, m, sum, v[210], ans[210], map1[210]

&quot;《算法导论》之‘图’&quot;:不带权二分图最大匹配(匈牙利算法)

博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利算法 1. 前言 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图.准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U.V中的顶点.如果存在这样的划分,则此图为一个二分图.二分图的一个等价定义是:不含有「含奇数条边的环」的图.