您的位置:首页 > 其它

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

2008-12-18 21:08 337 查看
网上关于匈牙利算法的模板很多,但往往只有一段代码,注释也不是很详细,以至于对ACM新手来说,可能得花上比较长的时间去理解,以下的代码是我从网上精心筛选的,算是标程吧,pku上3041,1469,1466都可以直接用以下代码计算最大匹配,再修改一下输入输出就AC了。
#define N 501
int useif
; //记录y中节点是否使用
int link
; //记录当前与y节点相连的x的节点
int mat

; //记录连接x和y的边,如果i和j之间有边则为,否则为
int gn,gm; //二分图中x和y中点的数目
int can(int t)
{
int i;
for(i=1;i<=gm;i++)
{
if(useif[i]==0 && mat[t][i])
{
useif[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,-1,sizeof(link));
for(i=1;i<=gn;i++)
{
memset(useif,0,sizeof(useif));
if(can(i)) num++;
}
return num;
}
采用邻接矩阵来存放二分图比较方便,若集合X中的i和集合Y中的j有边相连,则令mat[i][j]=1,link[j]来记录与当前的Y集合中j匹配的点,若没有匹配则值为-1,MaxMatch()中的循环对X中的元素逐个访问,从第一个元素开始can()再对Y中的元素开始逐一检查,看是否有于t相连的点,找到一个点后,用useif[]来记录在这一轮中这个点以用过,这样就相当于找到了一个匹配,当X中的另外一个点也与这个点相连时注意到link[j]不为-1,这样就再次从与之相连的X中的点出发,这就是一个DFS的过程,直至找到link[]=-1

代码出处http://old.blog.edu.cn/user3/Hailer/archives/2007/1829623.shtml
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: