HDU2063——过山车——————【二分图最大匹配模板】

/**

   未盖点:不与任何匹配边邻接的点

   匹配点:匹配边相连的顶点

   匹配:两两没有公共点的边集

   交替路:从未盖点出发,依次经过非匹配边,匹配边,非匹配边....所得到的路径

   增广路:交替路的终点是一个未盖点。

   增广路的长度为奇数,因为非匹配边比匹配边多一条。

   一个匹配是最大匹配的充要条件是不存在增广路。

   匈牙利算法,即不断增广,直到不能继续增广,达到最大匹配。

*/

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXV=550;             //顶点数
bool G[MAXV][MAXV],vis[MAXV];   //用邻接表存图,vis标记
int match[MAXV];                //保存X,Y匹配关系
int k,m,n;
int find_AP(int u){             //从Xu出发找增广路

    for(int i=1;i<=n;i++){      //遍历Yi

        if(!vis[i]&&G[u][i]){   //如果有路径可达且
            vis[i]=1;
            if(!match[i]||find_AP(match[i])){   
                                //如果Yi是未盖点或Yi非未盖点即Yi的匹配Xc还能增广
                match[i]=u;     //match[i]记录Yi与Xu匹配
                return true;    //返回找到一条增广路
            }
        }
    }
    return false;
}
int main(){

    int ans,a,b;
    while(scanf("%d",&k)!=EOF&&k){

        ans=0;                      
        memset(match,0,sizeof(match));
        memset(G,0,sizeof(G));
        scanf("%d%d",&m,&n);
        for(int i=0;i<k;i++){

            scanf("%d%d",&a,&b);
            G[a][b]=1;              //记录a--b间有路径
        }
        for(int i=1;i<=m;i++){      //用X向Y增广

            memset(vis,0,sizeof(vis));//清空标记
            if(find_AP(i))          //找Xi的增广路,找到后变量增加1,
                                    //直到不能增广,说明已经是最大匹配
                ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值