这个是学了好久的算法了。。终于腾出时间来写这篇博客了,希望借此加深一下这个算法的理解~
先来一个匈牙利算法的模板。
int M[MAX][MAX];int visit[MAX];
int un,vn,n,m;
int pre[MAX];
bool can(int u){
int v,j;
for(v=1;v<=vn;v++){
if(0==visit[v]&&1==M[u][v]){
visit[v]=1;
if(-1==pre[v]||can(pre[v])){
pre[v]=u;
return 1;
}
}
}
return 0;
}
int Solve(){
int i,sum=0;
memset(pre,0xff,sizeof(pre));
for(i=1;i<=un;i++){
memset(visit,0,sizeof(visit));
if(can(i))
sum++;
}
return sum;
}
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。
最大匹配:图中包含边数最多的匹配称为图的最大匹配。匈牙利就是来解决二分图的最大匹配问题的。
匈牙利算法的基本模式就是:
初始时最大匹配为空 |
下面给出一个伪代码:
bool 寻找从k出发的对应项出的可增广路
{
while (从邻接表中列举k能关联到顶点j)
{
if (j不在增广路上)
{
把j加入增广路;
if (j是未盖点 或者 从j的对应项出发有可增广路)
{
修改j的对应项为k;
则从k的对应项出有可增广路,返回true;
}
}
}
则从k的对应项出没有可增广路,返回false;
}
void 匈牙利hungary()
{
for i->1 to n
{
if (则从i的对应项出有可增广路)
匹配数++;
}
输出 匹配数;
}