二分图最大匹配 匈牙利算法的简单理解

来源:互联网 发布:mac装双系统好吗 编辑:程序博客网 时间:2024/04/29 10:22

(本文图片及被*标注内容来自CSDN博客:pi9nc)

基本概念—二分图

二分图:是图论中的一种特殊模型。若能将无向图G=(V,E)的顶点V划分为两个交集为空的顶点集,并且任意边的两个端点都分属于两个集合,则称图G为一个为二分图。


匹配:一个匹配即一个包含若干条边的集合,且其中任意两条边没有公共端点。如下图,图3的红边即为图2的一个匹配。


匹配边/匹配点:包含在匹配中的边及其端点。

非匹配边/非匹配点:不包含在匹配中的边及其端点。

最大匹配所含边数最多的匹配称为最大匹配。*

基本概念—匈牙利算法

交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边...形成的路径叫交替路。*

增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。

匈牙利算法

由增广路的性质,增广路中的匹配边总是比未匹配边多一条,所以如果我们放弃一条增广路中的匹配边,选取未匹配边作为匹配边,则匹配的数量就会增加。匈牙利算法就是在不断寻找增广路,如果找不到增广路,就说明达到了最大匹配。

算法模板(邻接表 & C++)

#include<iostream>using namespace std;const int N=20000,M=20000;struct edge{int u,v; edge *next;}e[M],*P=e,*point[N];int Link[N],used[N],n,m;inline void add_edge(int u,int v){++P;P->u = u; P->v = v; P->next = point[u]; point[u] = P;}bool dfs(int u){for(edge *j=point[u];j;j=j->next){if(used[j->v])continue;used[j->v]=true;if(Link[j->v]==0 || dfs(Link[j->v])){Link[j->v]=u;return true;}}return false;}int main(){//读入数据memset(Link,0,sizeof(Link));int cnt=0;for(int i=1;i<=n;i++){memset(used,0,sizeof(used));if(dfs(i))cnt++;}cout<<cnt<<endl;}


0 0
原创粉丝点击