POJ 1469 最大匹配

题目大意:N个学生,p们课,,每一门课程可以有多个学生选修,给出每门课程学生的选修情况,问:对于每门课程可不可以找到一个课代表( 前提是该学生要选修该门课程)

原题链接

二分图匹配:
只用在输入处理(即构造二分图时注意下就可以的)

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 300+2
int g[MAXN][MAXN];
int cp[MAXN],cn[MAXN];
int mk[MAXN];
int p,n;
int path(int u)  //DFS增广 
{
    for(int v=1;v<=n;v++) //遍历所有的学生
    {
        if(g[u][v] && !mk[v] ) //如果u与v邻接,即学生v选了课程u,且v未被访问过
        {
            mk[v]=1;
            if(!cn[v] || path(cn[v]))//v未匹配,或从cy[v]出发可以找到增广路
            {
                cp[u]=v; //把v匹配给u
                cn[v]=u; //把u匹配给v
                return 1;
            }
        }
    }
    return 0;
}
int max_match() //求最大匹配
{
    int res=0;
    memset(cp,0,sizeof(cp));
    memset(cn,0,sizeof(cn));
    for(int i=1;i<=p;i++) 
    {
        if(!cp[i]){ //从每个未盖点出发,寻求增广路
        memset(mk,0,sizeof(mk));
        res+=path(i);
        }
    }
    return res;
}
int main()
{
    int t,num,k;
    scanf("%d",&t);
    while(t--)
    {
        memset(g,0,sizeof(g));
        scanf("%d%d",&p,&n);
        for(int i=1;i<=p;i++)//课程标号从1-p
        {
            scanf("%d",&num);
            while(num--)
            {
                scanf("%d",&k);
                g[i][k]=1; //构造二分图
            }
        }
        int flag=max_match();
        if(flag==p)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值