HDU1469 COURSES
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17820
题意:一些课程给定能参加的学生名单,问是否有一种分配让每个课程都有一名不同的学生参加。
思路:二分模板题。通过search函数递归寻找是否存在增广路,若存在则标记点并匹配值加1。本题错误点是n和p的输入输反我也是醉了。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int const MAXN = 300+10;
int edge[MAXN][MAXN],use[MAXN],lin[MAXN];
int n,p,ans;
void init()
{
memset(edge,0,sizeof(edge));
memset(use,0,sizeof(use));
memset(lin,-1,sizeof(lin));
int i,j,k,tot,tt;
for(i=0; i<p; i++){
scanf("%d",&tot);
while(tot--){
scanf("%d",&tt);
edge[i][tt-1] = 1;
}
}
}
bool search(int a)
{
int i,j,k;
for(i=0; i<n; i++){
if(edge[a][i]==1 && use[i]==0){
use[i] = 1;
if(lin[i]==-1 || search(lin[i])){
// printf("lin = %d, a = %d\n",lin[i],a);
lin[i] = a;
return true;
}
}
}
return false;
}
void solve()
{
int i,j,k;
ans = 0;
for(i=0; i<p; i++){
memset(use,0,sizeof(use));
if(search(i))
ans++;
}
// printf("\nlin = \n");
// for(i=0; i<n; i++)
// printf("%d ",lin[i]);
}
void check()
{
printf("\nedge is \n");
int i,j;
for(i=0; i<p; i++){
for(j=0; j<n; j++)
printf("%d ",edge[i][j]);
printf("\n");
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1; i<=t; i++){
scanf("%d%d", &p, &n);
init();
// check();
solve();
if(ans == p)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}