您的位置:首页 > 其它

HDU 1083 Courses 匈牙利算法二分匹配(邻接矩阵存关系)

2017-04-26 11:35 471 查看
题目地址:点击打开链接

Courses

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 7474    Accepted Submission(s): 3656


[align=left]Problem Description[/align]
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:
 

[align=left]Sample Input[/align]

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

 

[align=left]Sample Output[/align]

YES
NO

题意:有P门课,和N个学生,为每一门课找一个课代表。输入P,N。然后每门课输入候选人数和候选编号。

问:能否为每一门课都匹配到课代表,输出YES或NO;

思路:匈牙利算法模板题。推荐一篇大神讲解:点击打开链接

以每一门课作为主动变量,学生为被动的。然后为每一门课去安排课代表,注意只能一一匹配,不能一个人干两门课。

代码:

//P门课,从N个学生中选课代表
//主动变量是课程,被动是学生
#include<stdio.h>
#include<string.h>
int map[310][310];
int stu[310];//记录学生选的课(记录被动变量)
int vis[310];//临时记录是否访问
int N,P;
int find(int course)//为课程course找学生课代表
{
for(int i=1;i<=N;i++)//遍历学生
{
if(vis[i]==0&&map[course][i]==1)//此学生还没访问 且能当这门课代表
{
vis[i]=1;//vis作用是保证对每个学生只一次
if(stu[i]==0 || find(stu[i]))//此学生未被选,或可以他可以换课
{
stu[i]=course;
return 1;
}
}
}
return 0;//查找失败
}
int hungary()
{
int sum=0;
for(int i=1;i<=P;i++)//为第i门课选课代表
{
memset(vis,0,sizeof(vis));
if(find(i))
sum++;
}
return sum;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(map,0,sizeof(map));
memset(stu,0,sizeof(stu));
scanf("%d%d",&P,&N);
for(int i=1;i<=P;i++)//第 i 门课程
{
int n;
scanf("%d",&n);//n个候选人
while(n--)
{
int x;//学生x

c164
scanf("%d",&x);
map[i][x]=1;
//map[i][x]=map[x][i]=1;
}
}
int sum=hungary();
if(sum==P)puts("YES");
else      puts("NO");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: