码迷,mamicode.com
首页 > 其他好文 > 详细

[二分图最大匹配]LuoGu P2417 课程

时间:2018-06-26 19:27:39      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:ems   size   memset   show   编号   就是   要求   namespace   最大匹配   

题目地址LuoGu P2417 课程

题目描述
n个学生去p个课堂,每一个学生都有自己的课堂,并且每个学生只能去一个课堂,题目要求能够安排每一个课堂都有人吗?

输入输出格式
输入格式:
第一行是测试数据的个数,

每组测试数据的开始分别是p和n,

接着p行,每行的开始是这个课堂的学生人数m,接着m个数代表该课堂的学生编号

输出格式:
如果该组数据能够这样安排就输出YES,否则输出NO。

输入输出样例
输入样例#1:

2
3 3
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1

输出样例#1:

YES
NO

说明
对于100%的数据, n\(\le 100\),\(m\le 20000\)


二分图最大匹配..裸的 没有什么难度 跑一遍就过了 唯一需要考虑的就是 如果n>m的话 我们就直接输出NO

扔代码..

//#define fre yes

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 20010 * 2;
int curch[maxn];
int head[maxn];
int ver[maxn];
int to[maxn];

bool Vis[maxn];

int n,m,k,tot,ans;

template<typename T>inline void read(T&x)
{
    x = 0;char c;int lenp = 1;
    do { c = getchar();if(c == '-') lenp = -1; } while(!isdigit(c));
    do { x = x * 10 + c - '0';c = getchar(); } while(isdigit(c));
    x *= lenp;
}

void addedge(int x,int y)
{
    ver[tot] = y;
    to[tot] = head[x];
    head[x] = tot++;
}

bool can(int x)
{
    for (int i=head[x];~i;i=to[i])
    {
        int y = ver[i];
        if(!Vis[y])
        {
            Vis[y] = 1;
            if(!curch[y]||can(curch[y]))
            {
                curch[y] = x;
                return 1;
            }
        } } return 0;
}

int main()
{
    read(k);
    while(k--)
    {
        // for (int i=0;i<maxn;i++) { curch[i] = 0;head[i] = -1;ver[i] = 0;to[i] = 0; }
        memset(curch,0,sizeof(curch));
        memset(head,-1,sizeof(head));
        memset(ver,0,sizeof(ver));
        memset(to,0,sizeof(to));
        ans = 0;tot = 0;

        read(n);read(m);
        for (int i=1;i<=n;i++)
        {
            int x;
            read(x);
            for (int j=1;j<=x;j++)
            {
                int y;
                read(y);
                addedge(i,y);
            }
        } 
        
        if(n > m)
        {
            puts("NO");
            continue;
        }
        
        for (int i=1;i<=n;i++)
        {
            memset(Vis,false,sizeof(Vis));
            if(can(i)) ans++;
        } if(ans == n) puts("YES");
        else puts("NO");
    } return 0;
}

[二分图最大匹配]LuoGu P2417 课程

标签:ems   size   memset   show   编号   就是   要求   namespace   最大匹配   

原文地址:https://www.cnblogs.com/Steinway/p/9230689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!