poj1469 二分图最大匹配 匈牙利算法BFS实现

                                                         POJ 1469

二分图讲解:点击打开链接

大致题意:

有n个学生和p门课程,每个人可以选0,1,2......门课程。给你每个学生喜欢的课程编号,然后问你是否能从n中选p个学生,使得每个学生所选的课程都不同且每门课程都有一个人选。

大致思路:

其实题意就是问你是否能找出p个1对1的关系。那么根据二分图最大匹配性质,我们只需找出最大匹配数,看是否和课程书相同,是的话,那就代表能成功。

直接套模板,我用的是BFS,据说BFS比DFS更稳定。

代码:

#include
#include
#include
#include
#include
using namespace std;
int pre[305],vis[305];pre数组用来存储路径,等更改匹配边时要用到。
int ml[305],mr[305];//左集合点的匹配点  右集合点的匹配点   
int p,n;
vectorV[30005];//vector存图
int MaxMatch()//bfs实现匈牙利算法
{
    int ans=0;
    memset(vis,0,sizeof(vis));
    memset(ml,-1,sizeof(ml));
    memset(mr,-1,sizeof(mr));
    for(int i=1; i<=p; i++)
    {
        if(ml[i]!=-1)continue;
        queueQ;
        Q.push(i);
        pre[i]=-1;
        int flag=0;//是否找到增广路
        while(!Q.empty()&&!flag)
        {
            int v=Q.front();
            Q.pop();
            for(int j=0; j=0)
                    {
                        pre[mr[to]]=v;//没找到增广路,记下路径
                    }
                    else//找到了
                    {
                        flag=1;
                        int d=v;
                        int e=to;
                        while(d!=-1)//更改路径
                        {
                            int temp=ml[d];
                            ml[d]=e;
                            mr[e]=d;
                            e=temp;
                            d=pre[d];
                        }
                    }
                }
            }
        }
        if(flag)ans++;//找到增广路,匹配边加一条

    }
    return ans;

}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {

        scanf("%d%d",&p,&n);
        int num,a;
        for(int i=1; i<=p; i++)
        {
            V[i].clear();
            scanf("%d",&num);
            for(int j=1; j<=num; j++)
            {
                scanf("%d",&a);
                V[i].push_back(a);
            }
        }
        int ans=MaxMatch();
        //printf("%d\n",ans);
        if(ans==p)
            printf("YES\n");
        else
            printf("NO\n");

    }
}

第一次做二分图类题,看了一下午,终于略有所懂,写一道简单题找找感觉~~~~~

你可能感兴趣的:(图论)