标准二分图匹配----匈牙利算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

                                                              ————度娘

看不懂没关系(我也看不懂qwq),下面我就讲一下二分图匹配的简单理解方式:

首先说明一下题:匈牙利村中有有n个壮汉(下边简称gay)有m个美女(下面简称bitch)有k对关系(有关系说明2人可以结婚)求最多有多少对夫妻。

提醒一句 不支持同性结婚,

输入:第一行 n m k

  第二行到k+1行 a b(表示gay a和bitch b有关系)

输出

  最多夫妻个数(即最大匹配个数)

很明显这是个裸的网络流

样例输入

4 4 6

1 1

1 2

1 4

2 1

2 3

3 2

4 4

样例输出

3

 

 讲下样例,顺便说下思路:

gay 1和bitch 1 2 4 有关系,为了保证最大匹配我们先让 gay 1和bitch 1连;

接着看gay 2,gay 2和bitch 1 3有关系,为了保证最大匹配我们让 gay 2和bitch 1连,

但这时gay 1已经和bitch 1连了,我们怎么做呢,

明显gay 1和bitch 2 4也有关系,gay 1想:忍了忍了,

于是开开心心(不乐意)地和bitch 2搞上了;

再看 gay 3只和bitch 2有关系,

但这时gay 1已经和bitch 2连了,我们怎么做呢,

明显gay 1和bitch 4也有关系,gay 1想:算了算了,

于是开开心心(不乐意)地和bitch 4搞上了;

再看 gay 4只和bitch 4有关系,

但 gay 1已经和bitch 4搞上了,而且gay 1的其他伪老婆也跑了,gay 1心想:mmp,干他娘的;

然后gay 4就吓跑了,发现没其他的bitch 和他有关系,于是孤独一生。

 

说完大体思路后,我们讲讲代码实现。我们可以用一个(bool) map【】【】储存二者之间的关系,每次遍历一遍判断该gay(或bitch)是否与另一个bitch(或gay)有关系,每次用个vis【】来判断是否能连,不能连就连下一个直到无点可连。这就是中心内容了。。。上代码吧。。。

#include<cstdio>
#include<cstring>
using namespace std;
int map[1006][1006];
bool vis[1005];
int link[1005];
int n,m,k,ans=0;
bool dfs(int a)
{
    for(int i=1;i<=n;i++)
    {
        if(map[a][i]==1&&!vis[i])
        {
            vis[i]=1;
            if(dfs(link[i])||link[i]==0)
            {
                link[i]=a;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);         //n男的m女的k关系数 
    int a,b;
    while(k--)
    {
        scanf("%d%d",&a,&b);
        map[a][b]=1;        //关联关系 
    }
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));    //刷新一遍 
        if(dfs(i)==true)            //判断能否不改变其他的点的匹配数的前提下使当前点得到匹配 
        ans++;
    }
    printf("%d\n",ans);
    return 0;
}

第一次讲课,可能讲不好,望大家包涵qwq....

欢迎指正,欢迎提问。

转载请注明——sxld-lgl

  

posted @ 2017-11-19 15:55  sxld-lgl  阅读(152)  评论(0)    收藏  举报