Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17858 | Accepted: 7038 |
Description
- 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
Input
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抣l 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.
Output
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
Source
題目大意:有P門課和N個學生,第i門課有counti個學生學習;每個學習i課的學生均可代表這個課;
問能否找出學生,每個學生只代表一門課,並且,沒有課時沒有學生代表的;
題目大概是求,對於一個二分圖的匹配,對於右邊的集合(或者左邊的集合)中的點,全是匹配點,不存在不匹配的點;
用匈牙利算法找出最大匹配後,便利右邊集合中的點(或者左邊集合中的點),看是否存在不匹配的點;
注意:此題如果用右集合中的點來考慮的話,注意在輸入時應將順序反一下。
代碼:
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define N 310
using namespace std;
int w[N][N];
int l[N];
int visit[N],v1,v2;
bool dfs(int x)
{
int i;
for(i=1;i<=v2;i++)
{
if(!visit[i]&&w[x][i])
{
visit[i]=1;
if(l[i]==0||dfs(l[i]))
{
l[i]=x;
return true;
}
}
}
return false;
}
int nmatch()
{
int i;
for(i=1;i<=v1;i++)
{
memset(visit,0,sizeof(visit));
dfs(i);
}
for(i=1;i<=v2;i++)
{
if(!l[i])//遍歷點看是否存在不匹配的點
return 0;
// printf("l[i] %d\n",l[i]);
}
return 1;
}
int main()
{
int t,p,q,n,i,j,d;
int ans;
scanf("%d",&t);
{
while(t--)
{
scanf("%d%d",&p,&n);
v1=n,v2=p;//v1,v2的大小也要換一下
memset(w,0,sizeof(w));
memset(l,0,sizeof(l));
for(i=1;i<=p;i++)
{
scanf("%d",&q);
for(j=0;j<q;j++)
{
scanf("%d",&d);
w[d][i]=1;///順序反一下(注意到這應該就沒問題了)
}
}
ans=nmatch();
printf("%s\n",ans==1?"YES":"NO");
}
}
return 0;
}