看了一个下午的匈牙利算法,感觉是似懂非懂哈
学习了一些基本的概念,比如什么是最大匹配,增广路径......
看了很多大佬的博客,我觉得我讲的话应该没有他们说得好,此处,传送门
2.匈牙利算法详解
以上都是对匈牙利算法的一些概念的讲解,我觉得还是很必要的看懂这些。
然后我贴一个匈牙利算法的模板,链接:匈牙利算法模板
讲的还是不错哒
插入一段匈牙利算法的模板,由此很多题目就可以套用了,当然套用的基础是理解!!
int vis[N]; //记录y中节点是否使用 0表示没有访问过,1为访问过
int link[N]; //记录当前与y节点相连的x的节点
int map[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
int gn,gm; //二分图中x和y中点的数目
int can(int t)
{
int i;
for(i=1;i<=gm;i++)
{
if(vis[i]==0&&map[t][i])
{
vis[i]=1;
if(link[i]==-1||can(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int i,num;
num=0;
memset(link,0xff,sizeof(link));
for(i=1;i<=gn;i++)
{
memset(vis,0,sizeof(vis));
if(can(i)) num++;
}
return num;
}
如杭电的hdu 1150 Machine Schedule ,我就是用这个模板做的。
#include<stdio.h>
#include<string.h>
#define N 202
int vis[N]; //记录y中节点是否使用 0表示没有访问过,1为访问过
int link[N]; //记录当前与y节点相连的x的节点
int map[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
int gn,gm; //二分图中x和y中点的数目
int can(int t)
{
int i;
for(i=0;i<gm;i++)//因题目而异了
{
if(vis[i]==0&&map[t][i])
{
vis[i]=1;
if(link[i]==-1||can(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int i,num;
num=0;
memset(link,0xff,sizeof(link));
for(i=0;i<gn;i++)//因题目而异了
{
memset(vis,0,sizeof(vis));
if(can(i)) num++;
}
return num;
}
int main()
{
int k;
while(scanf("%d",&gn),gn!=0)
{
scanf("%d%d",&gm,&k);
memset(map,0,sizeof(map));
while(k--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>0&&c>0)
{
map[b][c]=1;
}
}
printf("%d\n",MaxMatch());
}
}