匈牙利算法---解决最大匹配问题

来源:互联网 发布:童谣的知乎回答 编辑:程序博客网 时间:2024/04/28 18:15

这是一种用增广路求二分图最大匹配的算法。

讲解的很详细的博客:https://www.byvoid.com/blog/hungary/

至于基础知识,我就不多讲了。其实它就是一直在找出一条路径能把二分图的左半部分的其中一个未匹配节点和右半部分的其中一个未匹配节点加入到已经匹配的节点中去。这就是关键。那个博客讲的很详细了。看了之后都知道是具体情况。

下面我根据自己的理解实现了一下这个算法(DFS方式)。

#include<iostream>using namespace std;#define MAX_NUM  1024int Left=4;int Right=3;int vm[MAX_NUM];//节点对应的匹配节点int edge[MAX_NUM][MAX_NUM];//左右部分连接情况int count;bool isVisited[MAX_NUM];//每次找增广路的时候,都要对它进行重置int index=0;void init(){memset(edge,0,sizeof(edge));edge[0][4]=1;edge[0][6]=1;edge[1][6]=1;//edge[1][7]=1;edge[2][4]=1;edge[2][5]=1;edge[3][5]=1;edge[3][6]=1;}bool can(int m){for(int i=Left;i<Left+Right;i++){if(edge[m][i]){if(isVisited[i])continue;isVisited[i]=true;if(vm[i]==-1){cout<<m<<"->"<<i<<"";vm[m]=i;vm[i]=m;return true;}else{if(can(vm[i])){vm[m]=i;vm[i]=m;cout<<m<<"->"<<i<<"";return true;}}}}return false;}void main(){memset(vm,-1,MAX_NUM);init();for(int i=0;i<Left;i++){cout<<"第"<<index++<<"次为:";memset(isVisited,0,sizeof(isVisited));isVisited[i]=true;if(can(i))count++;elsecout<<"NULL";cout<<endl;}cout<<count<<endl;}