题目描述

«问题描述:

假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算法。

«编程任务:

对于给定的组卷要求,计算满足要求的组卷方案。

输入输出格式

输入格式:

第1行有2个正整数k和n (2 <=k<= 20, k<=n<= 1000)

k 表示题库中试题类型总数,n 表示题库中试题总数。第2 行有k 个正整数,第i 个正整数表示要选出的类型i的题数。这k个数相加就是要选出的总题数m。接下来的n行给出了题库中每个试题的类型信息。每行的第1 个正整数p表明该题可以属于p类,接着的p个数是该题所属的类型号。

输出格式:

第i 行输出 “i:”后接类型i的题号。如果有多个满足要求的方案,只要输出1个方案。如果问题无解,则输出“No Solution!”。

输入输出样例

输入样例#1:

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
输出样例#1:

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

Solution:

  题意容易理解,大致求的是n到题能不能组成k种类型且满足每种类型的数量要求。

  仔细思考,不难发现该题类似于匹配,因为一道题只能属于一种类型,那么这不就是类似于二分图匹配呀,只不过这里的类型能匹配多道题罢了,万变不离其宗嘛!所以我们可以用匈牙利算法来做,当然我还是弱弱地用最大流做做吧!

  首先,先统计所有类型包含的题目总数m,然后我们直接建立源点S连向每种类型,容量为该类型所含的题目个数,再每种类型连向可以匹配的题目,容量为1,最后每道题都连向汇点T。最后跑最大流,若ans!=m,说明没有匹配完全,若ans==m,输出时直接判断与每种类型相连的边容量是否为0(说明该边连接的题匹配过)且连向的点不为源点S(因为容量为0的边也有可能是源点连向某一类型的边的反向边)。输出的方法有许多种,若按我上述的方法输出,则加黑部分一定要写上,不然理论上可能爆0(但是洛谷数据水,最先没删调试语句有90分,开始以为是调试语句的问题,后来发现是没写加黑部分的语句,结果都有90分~神奇啊)

代码:

 // luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
using namespace std;
il int gi()
{
int a=;char x=getchar();bool f=;
while((x>''||x<'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=a*+x-,x=getchar();
return f?-a:a;
}
const int N=,inf=;
int n,m,k,s,t=,dis[N],h[N],cnt=,ans;
struct edge{
int to,net,v;
}e[N*];
il void add(int u,int v,int w)
{
e[++cnt].to=v,e[cnt].net=h[u],e[cnt].v=w,h[u]=cnt;
e[++cnt].to=u,e[cnt].net=h[v],e[cnt].v=,h[v]=cnt;
}
queue<int>q;
il bool bfs()
{
memset(dis,-,sizeof(dis));
q.push(s);dis[s]=;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=h[u];i;i=e[i].net)
if(dis[e[i].to]==-&&e[i].v>)dis[e[i].to]=dis[u]+,q.push(e[i].to);
}
return dis[t]!=-;
}
il int dfs(int u,int op)
{
if(u==t)return op;
int flow=,used=;
for(int i=h[u];i;i=e[i].net)
{
int v=e[i].to;
if(dis[v]==dis[u]+&&e[i].v>)
{
used=dfs(v,min(op,e[i].v));
if(!used)continue;
flow+=used,op-=used;
e[i].v-=used,e[i^].v+=used;
if(!op)break;
}
}
if(!flow)dis[u]=-;
return flow;
}
int main()
{
k=gi(),n=gi();int num,p;
for(int i=;i<=k;i++)num=gi(),m+=num,add(s,i,num);
for(int i=;i<=n;i++){
num=gi();
while(num--){
p=gi();add(p,i+k,);
}
add(i+k,t,);
}
while(bfs())ans+=dfs(s,inf);
if(ans!=m)printf("No Solution!");
else {
for(int i=;i<=k;i++)
{
printf("%d: ",i);
for(int j=h[i];j;j=e[j].net)
if(!e[j].v&&e[j].to)printf("%d ",e[j].to-k);
printf("\n");
}
}
return ;
}

 

洛谷 P2763 试题库问题(网络流24题之一)的更多相关文章

  1. [洛谷P2763]试题库问题

    题目大意:有 $k$ 种类型和 $n$ 个题目,每个题目会适应部分类型,第$i$个类型需要$s_i$的题,一道题只能满足一种类型,现要求出满足所有类型的题目的方案 题解:看到匹配,想到网络流,源点向试 ...

  2. 洛谷P2763 试题库问题(最大流)

    题意 $n$道试题,每道题有多种类别属性 抽取$m$道题组成试卷,要求包含指定的类型 输出方案 Sol 又是一道zz网络流 我的构图长这样,$k_i$表示第$i$道试题需要的数量 #include&l ...

  3. 洛谷P2763 试题库问题(最大流)

    传送门 网络流界的一股清流啊……终于没那么变态了…… 考虑一下怎么建图.对于每一个类型,我们从$S$向他连边,容量为它所需的题数,表明它要可以有这么多题,对于每一道题目,我们从它对应的类型向他连边,容 ...

  4. 洛谷 [P2763]试题库问题

    非常舒适的最大流 非常显然的建图方法,然而因为数组开小卡了很长时间 #include <iostream> #include <cstdio> #include <alg ...

  5. 洛谷 P2763 试题库问题【最大流】

    s向所有类别属性连流量为当前类别属性需要的个数的边,所有题目向t连流量为1的边(表示只能选一次),所有属性向含有它的题连容量为1的边.跑一变dinic,结果小于m则无解,否则看每一个类别属性连出去的题 ...

  6. 洛谷P4013数字梯形问题——网络流24题

    题目:https://www.luogu.org/problemnew/show/P4013 最大费用最大流裸题: 注意:在第二种情况中,底层所有点连向汇点的边容量应该为inf,因为可以有多条路径结束 ...

  7. 【题解】 P2763 试题库问题(网络流)

    P2763 试题库问题 考虑一个试题要被加入进答案的集合有什么条件? 是某种类型 只算作一次 就这两种且的限制,所以我们用串联的方式连接"类型点"和"作用点". ...

  8. P2763 试题库问题 (网络流 最大流)

    传送门 解题思路 比较简单的网络流,建图还是比较好想的.让源点向试题连流量为1的边,试题向所属类型连流量为1的边,类型向汇点连流量为需要此类试题的边.直接跑最大流,输出答案时找到那些满流的边所对的点. ...

  9. Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)

    Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...

随机推荐

  1. [arc068E]Snuke Line-[树状数组]

    Description 传送门 Solution 假如想直接YY对于每一个d会有多少种商品满足条件,em反正我搞不定. 然后大佬的题解告诉我说:搞不定?那就不搞它啊,反过来不就得了? 好吧.我们来考虑 ...

  2. [FJOI2014]最短路径树问题 长链剖分

    [FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...

  3. Retinex图像增强和暗通道去雾的关系及其在hdr色调恢复上的应用

    很多人都认为retinex和暗通道去雾是八杆子都打不着的增强算法.的确,二者的理论.计算方法都完全迥异,本人直接从二者的公式入手来简单说明一下,有些部分全凭臆想,不对之处大家一起讨论. 首先,为描述方 ...

  4. CI框架浅析(一)

            CodeIgniter 是一个小巧但功能强大的 PHP 框架,作为一个简单而“优雅”的工具包,它可以为开发者们建立功能完善的 Web 应用程序.本人使用CI框架有一段时间了,现在决定把 ...

  5. Struts 2(二):使用Struts2

    本文简单描述如何在Eclipse中使用使用Struts2,并介绍一下Struts2的配置文件 注:Struts2默认需要Java 5.0及其以上版本的运行环境支持,Web容器需要支持Servlet 2 ...

  6. JMeter怎样测试WebSocket

    一.安装WebSocket取样器 1.从JMeter插件管理器官网下载: https://jmeter-plugins.org/ 把这6个jar包放到C:\JMeter\apache-jmeter-3 ...

  7. Pairs Forming LCM LightOJ - 1236 素因子分解

    Find the result of the following code: long long pairsFormLCM( int n ) {    long long res = 0;    fo ...

  8. Linux环境下Java应用性能分析定位-CPU使用篇

    1     CPU热点分析定位背景 CPU资源还是很昂贵的,为了深刻感受到这种昂贵,间下图当前CPU的资源售价: 所以对于程序猿们来说,需要让程序合理高效的使用CPU资源.利用有限的CPU资源来解决完 ...

  9. 在Emacs 23里字体的调整(转自ChinaUnix.net)

    首先,在Emacs中,通过菜单Options --> Set Default Font,设置好你喜欢的字体. 然后,把光标放到你所在的字体上,用命令M-x describe-font来查看你当前 ...

  10. redis rdb aof比较

    Redis中数据存储模式有2种:cache-only,persistence; cache-only即只做为“缓存”服务,不持久数据,数据在服务终止后将消失,此模式下也将不存在“数据恢复”的手段,是一 ...