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

网上关于匈牙利算法的模板很多,但往往只有一段代码,注释也不是很详细,以至于对ACM新手来说,可能得花上比较长的时间去理解,以下的代码是我从网上精心筛选的,算是标程吧,pku上3041,1469,1466都可以直接用以下代码计算最大匹配,再修改一下输入输出就AC了。

#define N 501

int useif[N];   //记录y中节点是否使用

int link[N];   //记录当前与y节点相连的x的节点

int mat[N][N]; //记录连接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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值