Courses (匈牙利算法)

Courses

Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is possible to form a committee of exactly P students that satisfies simultaneously the conditions: 

. every student in the committee represents a different course (a student can represent a course if he/she visits that course) 

. each course has a representative in the committee 

Your program should read sets of data from a text file. The first line of the input file contains the number of the data sets. Each data set is presented in the following format: 

P N 
Count1 Student1 1 Student1 2 ... Student1 Count1 
Count2 Student2 1 Student2 2 ... Student2 Count2 
...... 
CountP StudentP 1 StudentP 2 ... StudentP CountP 

The first line in each data set contains two positive integers separated by one blank: P (1 <= P <= 100) - the number of courses and N (1 <= N <= 300) - the number of students. The next P lines describe in sequence of the courses . from course 1 to course P, each line describing a course. The description of course i is a line that starts with an integer Count i (0 <= Count i <= N) representing the number of students visiting course i. Next, after a blank, you'll find the Count i students, visiting the course, each two consecutive separated by one blank. Students are numbered with the positive integers from 1 to N. 

There are no blank lines between consecutive sets of data. Input data are correct. 

The result of the program is on the standard output. For each input data set the program prints on a single line "YES" if it is possible to form a committee and "NO" otherwise. There should not be any leading blanks at the start of the line. 

An example of program input and output:

Input

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

Output

YES
NO 

Sample Input

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

Sample Output

YES
NO 

Google翻译:

考虑一组N学生和P课程。每个学生访问零,一个或多个课程。您的任务是确定是否有可能组建一个完全符合P学生的委员会,同时满足以下条件:

。委员会中的每个学生代表不同的课程(如果学生访问该课程,学生可以代表课程)

。每门课程都有委员会的代表

您的程序应该从文本文件中读取数据集。输入文件的第一行包含数据集的数量。每个数据集以以下格式显示:

P N.
Count1 Student1 1 Student1 2 ... Student1 Count1
Count2 Student2 1 Student2 2 ... Student2 Count2
......
CountP StudentP 1 StudentP 2 ... StudentP CountP

每个数据集中的第一行包含两个由一个空格分隔的正整数:P(1 <= P <= 100) - 课程数和N(1 <= N <= 300) - 学生数。接下来的P行按顺序描述课程。从课程1到课程P,每行描述一门课程。当然,i的描述是以整数Count i(0 <= Count i <= N)开始的行,表示访问课程i的学生的数量。接下来,在空白之后,你会发现Count i的学生,访问课程,每两个连续分隔一个空白。学生编号为1到N的正整数。

连续数据集之间没有空行。输入数据是正确的。

程序的结果是标准输出。对于每个输入数据集,如果可以形成委员会,则程序在单行上打印“是”,否则打印在“否”。在线的开头不应该有任何前导空白。

思路:匈牙利模板题

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
#define N 505
int n,m,f[N],vis[N];
vector<int>a[N];
int find(int x)
{
    for(int i=0;i<a[x].size();i++)
    {
        int v=a[x][i];
        if(!vis[v])
        {
            vis[v]=1;
            if(f[v]==0||find(f[v]))
            {
                f[v]=x;
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(f,0,sizeof(f));
        scanf("%d%d",&m,&n);
        int k,x,flag=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&k);
            while(k--)
            {
                scanf("%d",&x);
                a[i].push_back(x);
            }
        }
        for(int i=1;i<=m;i++)
        {
            memset(vis,0,sizeof(vis));
            if(!find(i)){flag=1;printf("NO\n");break;}
        }
        if(!flag) printf("YES\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/chimchim04/article/details/81411172
今日推荐