zoukankan      html  css  js  c++  java
  • HDU 2063 过山车 二分匹配

    解题报告:有m个女生和n个男生要结成伴坐过山车,每个女生都有几个自己想选择的男生,然后要你确定最多能组成多少对组合。

    最裸的一个二分匹配,这是我第一次写二分匹配,给我最大的感受就是看那些人讲的匈牙利算法真不知道他们是怎么写的,看着就觉得很麻烦,好像很难的样子,我这是看第二次,最后还是没看懂,最后实在没办法了,直接看代码了,才发现,原来二分匹配可以用很简单的描述,下面我就用我的语言描述一下:

    假如分成两个集合X和Y,我们可以从X 中的第一个元素枚举到最后一个,然后每次枚举的内容就是从X 出发,找这个元素能不能跟Y中的一个元素进行匹配,关键就是这个查找的函数,这个可以用dfs或者bfs,这里我就讲用dfs实现的,枚举X中的一个元素的时候,我们就从这个元素出发,从Y的元素开始枚举,如果Y的有元素还没有被匹配,则返回,就将这两个元素匹配起来,而如果这个Y中的元素在前面已经被匹配过了,那么就递归,看跟Y匹配的是X中的哪一个元素,其实说白了就是看X中的这个元素还能不能跟Y中的其它元素匹配,就是说把X中的这个元素当前已经匹配的Y中的元素让出来,让给当前正在匹配的那个元素,而自己去寻找是否有其它的元素跟自己匹配,这样一直下去之后,就能达到最多的匹配的效果了。

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn = 500+3;
     4 int map[maxn][maxn],visit[maxn],pipei[maxn],k,m,n,x,y;
     5 
     6 int dfs(int x) {
     7     for(int i = 1;i<=n;++i)
     8     if(!visit[i] && map[x][i]) {
     9         visit[i] = 1;
    10         if(!pipei[i] || dfs(pipei[i])) {
    11             pipei[i] = x;
    12             return 1;
    13         }
    14     }
    15     return 0;
    16 }
    17 
    18 int main() {
    19     while(scanf("%d",&k),k) {
    20         scanf("%d%d",&m,&n);
    21         memset(map,0,sizeof(map));
    22         memset(pipei,0,sizeof(pipei));
    23         while(k--) {
    24             scanf("%d%d",&x,&y);
    25             map[x][y] = 1;  //切不可加上map[y][x]也等于1 
    26         }
    27         int tot = 0;
    28         for(int i = 1;i<=m;++i) {
    29             memset(visit,0,sizeof(visit));
    30             tot += dfs(i);
    31         }
    32         printf("%d
    ",tot);
    33     }
    34     return 0;
    35 }
    View Code
  • 相关阅读:
    第二章、Java内存区域与内存溢出异常
    第二章、Java内存区域与内存溢出异常
    腾讯//格雷编码
    腾讯//格雷编码
    数据结构5.5_广义表的递归算法
    数据结构5.4_m元多项式的表示
    数据结构4.2_串操作应用举例_建立词索引表
    数据结构3_栈和队列
    数据结构2_线性表
    数据结构1_绪论
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3253773.html
Copyright © 2011-2022 走看看