链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1083

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82834#problem/C

 

一共有N个学生跟P门课程,一个学生可以任意选一

门或多门课,问是否达成:

  1.每个学生选的都是不同的课(即不能有两个学生选同一门课)

  2.每门课都有一个代表(即P门课都被成功选过)

 

 

现想组建一个委员会,委员会中的每个学生都要代表不同的课程,且每个课程都有它的代表。

算法分析:这正符合二分图最大匹配的条件。把课程作为二分图中X节点集合,得到最大匹配,如果匹配数等于课程数,则匹配与Y集合的交集,就可看成是这样一个委员会,则输出YES,否则,输出NO。

 

 

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 305
#define INF 0x3f3f3f3f

int n, m, un, vn, G[N][N], used[N], p[N];

int Find(int u)
{
    for(int i=1; i<=vn; i++)
    {
        if(G[u][i] && !used[i])
        {
            used[i] = 1;
            if(p[i]==-1 || Find(p[i]))
            {
                p[i] = u;
                return 1;
            }
        }
    }
    return 0;
}

int hungary()  //匈牙利算法
{
    int ans = 0;
    memset(p, -1, sizeof(p));

    for(int i=1; i<=un; i++)
    {
        memset(used, 0, sizeof(used));
        if(Find(i)) ans++;
    }
    return ans;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int i, j, v, k;

        scanf("%d%d", &n, &m);

        memset(G, 0, sizeof(G));
        for(i=1; i<=n; i++)
        {
            scanf("%d", &k);
            for(j=1; j<=k; j++)
            {
                scanf("%d", &v);
                G[i][v] = 1;
            }
        }

        un = n;
        vn = m;

        if(un==hungary()) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

 

傻傻的刷题,加油!

posted on 2015-08-11 09:16  栀蓝  阅读(176)  评论(0编辑  收藏  举报

levels of contents