HDU-1083-Courses(最大匹配)

链接:

https://vjudge.net/problem/HDU-1083#author=HUCM201732

题意:

题目大意: 一共有N个学生跟P门课程,一个学生可以任意选一 门或多门课,问是否达成:
1.每个学生选的都是不同的课(即不能有两个学生选同一门课)

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

输入为:

第一行一个T代表T组数据

P N(P课程数, N学生数)

接着P行:

第几行代表第几门课程,首先是一个数字k代表对这门课程感兴趣的同学的个数,接下来是k个对这门课程感兴趣同学的编号。

输出为:

若能满足上面两个要求这输出”YES”,否则为”NO”

注意:是课程匹配的学生,学生没课上没事.....

思路:

二分图最大匹配。考虑匹配数和课程数的关系即可.

代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <map>
using namespace std;

const int MAXN = 500;
int Linked[MAXN], Vis[MAXN];
vector<int> G[MAXN];
int n, m, p;
int row, col;

bool Dfs(int x)
{
    for (int i = 0;i < G[x].size();i++)
    {
        int nextnode = G[x][i];
        if (Vis[nextnode])
            continue;
        Vis[nextnode] = 1;
        if (Linked[nextnode] == -1 || Dfs(Linked[nextnode]))
        {
            Linked[nextnode] = x;
            return true;
        }
    }
    return false;
}

int Solve()
{
    int cnt = 0;
    memset(Linked, -1, sizeof(Linked));
    for (int i = 1;i <= p;i++)
    {
        memset(Vis, 0, sizeof(Vis));
        if (Dfs(i))
            cnt++;
    }
    return cnt;
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        cin >> p >> n;
        if (p > n)
        {
            cout << "NO" << endl;
            continue;
        }
        for (int i = 1;i <= p;i++)
            G[i].clear();
        for (int i = 1;i <= p;i++)
        {
            int num, v;
            cin >> num;
            while (num--)
            {
                cin >> v;
                G[i].push_back(v);
            }
        }
        int cnt = Solve();
        if (cnt < p)
            cout << "NO" << endl;
        else
            cout << "YES" << endl;
    }

    return 0;
}
posted @ 2019-07-10 00:23  YDDDD  阅读(245)  评论(0编辑  收藏  举报