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

来源:互联网 发布:工作日记软件 编辑:程序博客网 时间:2024/05/17 22:06

/**

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

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

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

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

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

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

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

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

*/

#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
原创粉丝点击