二分图匹配(基础)——过山车 ( HDU 2063 )

  • 题目链接:
    http://acm.hdu.edu.cn/showproblem.php?pid=2063

  • 分析&题解:
    这是道非常裸的二分图匹配,建好图后,直接用匈牙利DFS搜索即可。(这里采用遍历女生节点,找男生匹配,因为二分图以及给好了,并且确定左边是女生节点,右边是男生节点,所以可以这样做,如果混合给参考二分图匹配/判断中的匈牙利算法写法)

  • 关键步骤解释:

1.DFS代码:

bool DFS(int x)//搜索女生节点x
{
    for(int i=1;i<=m;i++)//找男生匹配
    {
        if(!Edges[x][i]||flag[i])//i不在x出发的交替路里或者只是交替路不是增广路。
            continue;
        flag[i] = 1;//生成交替路;
        if(!mark[i]||DFS(mark[i])) //i点未被匹配,或者i已经被匹配时寻找男生i所对应的女生的增广路,如果那个女生能找到另一条增广路径,即有另外的男生可以匹配那就更换
        {
            mark[i] = x;
            return 1;
        }
    }
    return 0;
}

2.Hungarian算法:

void Hungarian()
{
    int ans = 0;
    memset(mark, 0, sizeof(mark));//先初始化匹配数组为0
    for(int i=1;i<=g;i++)
    {
        memset(flag, 0, sizeof(flag));//每次初始化交替路数组为0
        if(DFS(i))
        {
            ans++;//匹配成功就++;
        }
    }
    cout << ans << endl;
}

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

bool Edges[666][666];
int mark[666];
bool flag[666];
int k,g,m;

void input()
{
    for(int i=0;i<k;i++)
    {
        int x,y;
        cin >> x >> y;
        Edges[x][y] = 1;
    }
}

bool DFS(int x)
{
    for(int i=1;i<=m;i++)
    {
        if(!Edges[x][i]||flag[i])
            continue;
        flag[i] = 1;
        if(!mark[i]||DFS(mark[i]))
        {
            mark[i] = x;
            return 1;
        }
    }
    return 0;
}

void Hungarian()
{
    int ans = 0;
    memset(mark, 0, sizeof(mark));
    for(int i=1;i<=g;i++)
    {
        memset(flag, 0, sizeof(flag));
        if(DFS(i))
        {
            ans++;
        }
    }
    cout << ans << endl;
}

int main()
{
    while(cin >> k && k)
    {
        cin >> g >> m ;
        memset(Edges, 0, sizeof(Edges));
        input();
        Hungarian();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值