【线性规划与网络流24题 7】试题库问
Time Limit:10000MS Memory Limit:65536K
Total Submit:28 Accepted:8
Case Time Limit:1000MS
Description
假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算法。
编程任务:
对于给定的组卷要求,计算满足要求的组卷方案
由于本OJ无Special Judge , 所以只需要判断是否存在满足要求的组卷方案
Input
文件第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000)k 表示题库中试题类型总数,n 表示题库中试题总数。
第2 行有k 个正整数,第i 个正整数表示要选出的类型i 的题数。这k个数相加就是要选出的总题数m。
接下来的n行给出了题库中每个试题的类型信息。
每行的第1 个正整数p表明该题可以属于p类,接着的p个数是该题所属的类型号。
Output
一行,包含一个字符串 如果存在,输出"YES"(不包含引号), 如果不存在,输出"No Solution!"(不包含引号)
Sample Input
3 15
3 3 4
2 1 2
1 3
1 3
1 3
1 3
3 1 2 3
2 2 3
2 1 3
1 2
1 2
2 1 2
2 1 3
2 1 2
1 1
3 1 2 3
Sample Output
YES
Source
感谢 Wo_ai_WangYuan 修改题目并放上数据
建图:源点和每道题连容量为1的边,每道题与其所属的类型连容量为1的边,每个类型与汇点连容量为所需量的边
跑最大流,如果maxflow==sum(sum为所需的试题数)输出yes
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1005,inf=1e9;
inline void _read(int &x){
char t=getchar();bool sign=true;
while(t<'0'||t>'9')
{if(t=='-')sign=false;t=getchar();}
for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
if(!sign)x=-x;
}
int n,k,g[maxn][maxn+25],op,ed,maxflow;
int vd[2005],dis[2005];
int dfs(int u,int flow){
if(u==ed)return flow;
int v,temp,delta=0;
for(v=1;v<=ed;v++)
if(g[u][v]&&dis[u]==dis[v]+1){
temp=dfs(v,min(flow-delta,g[u][v]));
g[u][v]-=temp;
g[v][u]+=temp;
delta+=temp;
if(delta==flow||dis[op]>=ed)return delta;
}
if(dis[op]>=ed)return delta;
vd[dis[u]]--;
if(vd[dis[u]]==0)dis[op]=ed;
dis[u]++;
vd[dis[u]]++;
return delta;
}
int main(){
cin>>k>>n;
int i,j,x,m,sum=0;
op=n+k+1,ed=op+1;
for(i=1;i<=k;i++){
_read(x);
g[i+n][ed]=x;
sum+=x;
}
for(i=1;i<=n;i++){
_read(m);
g[op][i]=1;
while(m--){
_read(x);
g[i][x+n]=1;
}
}
while(dis[op]<ed)maxflow+=dfs(op,inf);
if(maxflow==sum)puts("YES");
else puts("No Solution!");
}