zoukankan      html  css  js  c++  java
  • COGS732. [网络流24题] 试题库

    «问题描述:
    假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算法。
    «编程任务:
    对于给定的组卷要求,计算满足要求的组卷方案。
    «数据输入:
    由文件testlib.in提供输入数据。文件第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000)k 表示题库中试题类型总数,n 表示题库中试题总数。第2 行有k 个正整数,第i 个正整数表示要选出的类型i 的题数。这k个数相加就是要选出的总题数m。接下来的n行给出了题库中每个试题的类型信息。每行的第1 个正整数p表明该题可以属于p类,接着的p个数是该题所属的类型号。
    «结果输出:
    程序运行结束时,将组卷方案输出到文件testlib.out 中。文件第i 行输出 “i:”后接类型i的题号。如果有多个满足要求的方案,只要输出1 个方案。如果问题无解,则输出“NoSolution!”。
    输入文件示例
    testlib.in
    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

    输出文件示例

    testlib.out

    1: 1 6 8
    2: 7 9 10
    3: 2 3 4 5

    网络流 最大流

    如果最大流等于m,那么有解,遍历从题型到题号的所有边,记录答案即可

      1 /*by SilverN*/
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #include<queue>
      9 using namespace std;
     10 const int INF=1e9;
     11 const int mxn=1050;
     12 int read(){
     13     int x=0,f=1;char ch=getchar();
     14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     16     return x*f;
     17 }
     18 struct edge{
     19     int v,nxt,f;
     20 }e[mxn*80];
     21 int hd[mxn],mct=1;
     22 void add_edge(int u,int v,int f){
     23     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;
     24  
     25     return;
     26 }
     27 void insert(int u,int v,int f){
     28     add_edge(u,v,f);add_edge(v,u,0);return;
     29 }
     30 int n,k,S,T;
     31 int d[mxn];
     32 bool BFS(){
     33     memset(d,0,sizeof d);
     34     queue<int>q;
     35     q.push(S);
     36     d[S]=1;
     37     while(!q.empty()){
     38         int u=q.front();q.pop();
     39         for(int i=hd[u];i;i=e[i].nxt){
     40             int v=e[i].v;
     41             if(!d[v] && e[i].f){
     42                 d[v]=d[u]+1;
     43                 q.push(v);
     44             }
     45         }
     46     }
     47     return d[T];
     48 }
     49 int DFS(int u,int lim){
     50     if(u==T)return lim;
     51     int tmp,f=0;
     52     for(int i=hd[u];i;i=e[i].nxt){
     53         int v=e[i].v;
     54         if(d[v]==d[u]+1 && e[i].f){
     55             tmp=DFS(v,min(lim,e[i].f));
     56             e[i].f-=tmp;
     57             e[i^1].f+=tmp;
     58             lim-=tmp;
     59             f+=tmp;
     60             if(!lim)return f;
     61         }
     62     }
     63     d[u]=0;
     64     return f;
     65 }
     66 int Dinic(){
     67     int res=0;
     68     while(BFS())res+=DFS(S,INF);
     69     return res;
     70 }
     71 vector<int>q[mxn];
     72 void Print(){
     73     int i,j;
     74     for(i=1;i<=k;i++){
     75         for(j=hd[i];j;j=e[j].nxt){
     76 //            printf("u:%d v:%d f:%d
    ",i,e[j].v,e[j].f);
     77             if(e[j^1].f) q[i].push_back(e[j].v-k);
     78         }
     79     }
     80     for(i=1;i<=k;i++){
     81         printf("%d:",i);
     82         for(j=0;j<q[i].size();j++){
     83             printf(" %d",q[i][j]);
     84         }
     85         printf("
    ");
     86     }
     87     return;
     88 }
     89 int m=0;
     90 int main(){
     91     freopen("testlib.in","r",stdin);
     92     freopen("testlib.out","w",stdout);
     93     int i,j;
     94     k=read();n=read();
     95     S=0;T=k+n+1;
     96     int x,y;
     97     for(i=1;i<=k;i++){
     98         x=read();
     99         insert(S,i,x);
    100         m+=x;
    101     }
    102     for(i=1;i<=n;i++){
    103         y=read();
    104         for(j=1;j<=y;j++){
    105             x=read();
    106             insert(x,i+k,1);
    107         }
    108     }
    109     for(i=1;i<=n;i++)insert(i+k,T,INF);
    110     int ans=Dinic();
    111     if(ans==m)Print();
    112     else printf("NoSolution!
    ");
    113     return 0;
    114 }
  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6240257.html
Copyright © 2011-2022 走看看