HDU 1083 Courses(二分匹配(dfs详解))


趣味匈牙利算法(DFS方法详解)


但是首先要分清楚这二分匹配是如何匹配的


是拿谁去匹配谁


主要表现为存图问题


这道题的图是如何存的,到底是存双向图还是存单向图


根据题意的理解,好像是每个学生可以匹配课程,也可以课程匹配学生


乍一看好像是个双向图~~~


但是这里用双向图就会很悲惨的WA


但是仔细读题,学生要比课程多····


意思就是,可能课程匹配完了,还剩下很多的学生


而我们要的结果是课程必须匹配学生,但是学生可以有剩余


那么用学生去匹配课程


即:对于每一个课程,我们都用DFS去寻找相对应的学生


如果反了会造成什么样的后果?


match里面存的变为学生对应的课程


如果学生数小于课程数,那么也会有可能输出YES


#include<bits/stdc++.h>
using namespace std;
const int maxn=310;
bool e[maxn][maxn];
bool vis[maxn];
int match[maxn];
int p,n;
bool find(int u)
{
    for(int i=1; i<=n; i++) //这里是N不是P(p代表课程,n代表人数)
    {
        if(!vis[i]&&e[u][i])
        {
            vis[i]=1;
            if(!match[i]||find(match[i]))
            {
                match[i]=u;
                return true;
            }
        }
    }
    return false;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(e,0,sizeof(e));
        scanf("%d%d",&p,&n);
        for(int i=1; i<=p; i++)//输入
        {
            int m,x;
            scanf("%d",&m);
            for(int j=1; j<=m; j++) //存图
            {
                scanf("%d",&x);
                e[i][x]=1;        //只能存单向图,存双向图会WA
            }
        }
        int flag=0;
        memset(match,0,sizeof(match));
        for(int i=1; i<=p; i++)//对于每一门的课程,寻找与之匹配的学生
        {
            memset(vis,0,sizeof(vis));
            if(find(i))
            {
                flag++;
            }
        }
        if(flag!=p)
            printf("NO\n");
        else
            printf("YES\n");
    }
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值