二分图匹配

   Matrix67在博客里这样写的。哈哈,自己稍微有点自信,Matrix67也是研究了几个小时的。

 

    “研究了几个小时,终于明白了。说穿了,就是你从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现。找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作,直到找不到这样的路径为止。”

 

     然后找了个代码。

 

     然后发现有个地方与自己理解的dfs找增广路有点不同,就是与自己模拟所得的结果不同。。  后来自己调试模拟了一遍,原来是忘了memset(flag,0,sizeof(flag))了。。

     果然自己亲自动手一下还是有益处的。也许我该自己看完思路写个dfs,可就怕自己写的不如标程好。。囧了。

  

     关于图理解比较好的是这个:http://kukumayas.iteye.com/blog/1075610

 

    但二分图的知识还多了去了。。。 详见这个,也许能做个题纲?:http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657446.html

 

     顺便水了一题HDU2063。  接下来攻带权的最优二分图匹配。

   

   

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn=1000;

int map[maxn][maxn];
int flag[maxn],pre[maxn];
int n,m,sum;

bool find(int u)
{
    for(int i=1;i<=m;i++) //m个男生
    {
        if(map[u][i]&&!flag[i])
        {
            flag[i]=1;
            if(pre[i]==-1||find(pre[i])) //dfs找增广路
            {
                pre[i]=u;
                return true;
            }
        }
    }
    return false; //不要忘写
}

void hungary()
{
    sum=0;
    memset(pre,-1,sizeof(pre));
    for(int i=1;i<=n;i++)
    {
        memset(flag,0,sizeof(flag));//囧了,每次都要清零flag...
        if(find(i))
            sum++;
    }
}

int main()
{
    int num,girl,boy;
    while(scanf("%d",&num)!=EOF)
    {
        if(!num) break;
        else scanf("%d%d",&n,&m);
        memset(map,0,sizeof(map));
        for(int i=1;i<=num;i++)
        {
            scanf("%d%d",&girl,&boy);
            map[girl][boy]=1;
        }
        hungary();
        printf("%d\n",sum);
    }
    return 0;
}


 

 

   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值