2020-08-05——匈牙利算法

匈牙利算法


昨天组队赛做题,其中有一个题用到了匈牙利算法,突然想起了这道题。

这道题比昨天做的那道题题目描述更加清晰,匈牙利算法的实质就是二分图的最大匹配。

例题——磕cp

Description

Alice喜欢嗑cp,她总是幻想她喜欢的男明星可以和她喜欢的女明星处cp, 已知n个男,m个女(男明星编号从1到n,女明星编号1到m),k组有可能发展成cp关系的组合, 一个人最多只能和一名异性处cp,Alice想知道她最多能嗑几组cp?
Input

第一行输入三个整数n,m,k(1<=n,m<=500,1<=k<=5e4),分别表示男明星个数,女明星个数,和有可能发展成cp的组合。接下来输入k行,每行两个整数u,v(1<=u<=n,1<=v<=m)表示编号为编号为u的男与编号为v的女可能成为cp。
Output

输出一个整数,表示Alice最多能嗑几组cp。
Sample
Input

2 3 4

1 1

1 3

2 1

2 2

Output

2

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define max 510
int line[max][max];//存储可以成为cp的人
int memory[max];//
int girl[max];//记录和女孩磕成cp的男孩
int n,m,k,x,y;
bool f(int x)
{
    
    
    int i;
    for(i=0; i<m; i++)
    {
    
    
        if(line[x][i]&&!memory[i])//如果两者可以磕cp并且该男孩和该女孩以前没有尝试过组cp
        {
    
    
            memory[i]=1;//已经尝试,下面代码为尝试的过程
            if(girl[i]==-1||f(girl[i]))//如果该女孩目前没有男孩或者和该女孩组cp的男孩可以腾位置
            {
    
    
                gril[i]=x;//匹配成功
                return true;
            }
        }
    }
    return false;
}
int g()
{
    
    
    int i,sum=0;
    for(i=0; i<n; i++)//遍历
    {
    
    
        memset(memory,0,sizeof(memory));
        if(f(i))sum++;
    }
    return sum;
}
int main()
{
    
    
    scanf("%d %d %d",&n,&m,&k);
    memset(girl,-1,sizeof(girl));//如果编号从零开始,这里初始化不要初始化为0
    memset(line,0,sizeof(line));
    while(k--)
    {
    
    
        scanf("%d %d",&x,&y);
        line[x][y]=1;
    }
    printf("%d\n",g());
    return 0;
}

哎,做个题都是cp,天天打代码的我们学校什么时候给分配对象啊!!!

猜你喜欢

转载自blog.csdn.net/rookie636/article/details/107823129