题意:

       有N个女生想跟自己的一个或者多个男生做在一起。然后要你算出最后能够匹配出多少对。

解题思路:

       这道题是明显的二分匹配题目。有个强大的算法:匈牙利算法,确实很凶,这算法挺牛叉。

       这道题属于单边匹配。

       算法的大体过程:

先让图的左边去右边找匹配项,(右边可能有多个),暂时先找一个,然后再由左边的下一个项可是找,如果有刚刚好剩下的符合自己的项就添加,若不存在,则要调用递归函数path(macth[v]),然后上一项从新匹配,知道全部项都满足为止即为最大的匹配数。

感觉讲得不明不白吧。结合代码,还有左边的图,自己画一遍,就有思路了。试试看。

      

 

 

 

 

 

 

关于二分图的详细介绍:

发发牢骚:

            这一次贡献了一个WA,因为我得nv=MAXV,所以path函数中的关于nv的,不能加“=”号,这是细节,分析下就出来了。以后要多用脑子想想。

代码:

#include<iostream> 
#include<stdio.h> 
using namespace std; 
 
const int MAXV=505
 
bool mat[MAXV][MAXV];//mat[u][v],从u到v是否连通 
int nv,match[MAXV];//nv是结点数,match[v]表示右边的节点v的匹配项u(v是图的右边,v是图的左边,结合上面的那个图) 
int visited[MAXV];//访问过的点 
 
int path(int u)//找u的匹配项 

    int v; 
    for(v=1;v<=nv;v++) 
    { 
        if(mat[u][v]&&!visited[v]) 
        { 
            visited[v]=1
            if(match[v]==-1||path(match[v])) 
            { 
                match[v]=u; 
                return 1
            } 
        } 
    } 
    return 0

 
int max_match()//求最大匹配数 

    int u,ans=0
    memset(match,-1,sizeof(match)); 
    for(u=1;u<=nv;u++) 
    { 
        memset(visited,0,sizeof(visited)); 
        ans+=path(u); 
    } 
    return ans; 

 
void init() 

    for(int i=0;i<MAXV;i++) 
        for(int j=0;j<MAXV;j++) 
        { 
            mat[i][j]=0
        } 

int main(void

    int u,v,cas,girl,boy; 
    while(scanf("%d",&cas),cas) 
    { 
        nv=MAXV-1;//注意减1,细节,上面的点都是<=nv的 
        scanf("%d%d",&girl,&boy);//女数,男数,这一句是没有用的 
        init(); 
        for(int i=1;i<=cas;i++) 
        { 
            scanf("%d%d",&u,&v);//u 到 v连通,即女生u能够接受男生v 
            mat[u][v]=1
        } 
        int count=max_match(); 
        printf("%d\n",count); 
    } 
    return 0
     

 

 

posted on 2011-08-22 01:19  cchun  阅读(207)  评论(0编辑  收藏  举报