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

Description

问题描述:

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

编程任务:

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

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

第i 行输出 “i:”后接类型i的题号。如果有多个满足要求的方案,只要输出1个方案。如果问题无解,则输出“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

1: 1 6 8

2: 7 9 10

3: 2 3 4 5

Http

Libre:https://loj.ac/problem/6006

Luogu:https://www.luogu.org/problem/show?pid=2763

Source

网络流,最大流

解决思路

题目的描述有些问题,应该是一道题目如果选择了作为这种类型就不能选择为另外一种类型了。

对于每一种类型的要求,从源点连一条容量为要求数目的边到类型;对于每一道试题,连从对应的类型到试题容量为1的边,同时从试题到汇点连一条容量为1的边。这样就可以保证一个试题只能选择作为一种类型。然后跑最大流即可。

若最大流等于所有类型要求数量之和(即从源点出发的所有边满流),则说明有解,否则无解。

另:这里使用Dinic求解最大流,可以参考我的这篇文章

代码

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxN=2000;
  8. const int maxM=maxN*maxN;
  9. const int inf=2147483647;
  10. class Edge
  11. {
  12. public:
  13. int u,v,flow;
  14. };
  15. int n,m;
  16. int cnt=-1;
  17. int Head[maxN];
  18. int Next[maxM];
  19. Edge E[maxM];
  20. int depth[maxN];
  21. int cur[maxN];
  22. int Q[maxN];
  23. void Add_Edge(int u,int v,int flow);
  24. bool bfs();
  25. int dfs(int u,int flow);
  26. int main()
  27. {
  28. memset(Head,-1,sizeof(Head));
  29. int sum=0;
  30. scanf("%d%d",&n,&m);
  31. for (int i=1;i<=n;i++)
  32. {
  33. int num;
  34. scanf("%d",&num);
  35. sum+=num;//统计总类型要求数量
  36. Add_Edge(0,i,num);//连边源点到类型
  37. }
  38. for (int i=1;i<=m;i++)
  39. {
  40. int p;
  41. scanf("%d",&p);
  42. for (int j=1;j<=p;j++)
  43. {
  44. int u;
  45. scanf("%d",&u);
  46. Add_Edge(u,n+i,1);//连边类型到题目
  47. }
  48. Add_Edge(n+i,n+m+1,1);//连边题目到汇点
  49. }
  50. int Ans=0;//求解最大流
  51. while (bfs())
  52. {
  53. for (int i=0;i<=n+m+1;i++)
  54. cur[i]=Head[i];
  55. while (int di=dfs(0,inf))
  56. Ans+=di;
  57. }
  58. if (Ans<sum)//若最大流小于要求总数,则说明无解
  59. {
  60. cout<<"No Solution!"<<endl;
  61. return 0;
  62. }
  63. for (int i=1;i<=n;i++)//有解,则输出一种方案
  64. {
  65. cout<<i<<": ";
  66. for (int j=Head[i];j!=-1;j=Next[j])
  67. {
  68. int v=E[j].v;
  69. if ((v>=n+1)&&(v<=n+m)&&(E[j].flow==0))
  70. cout<<v-n<<" ";
  71. }
  72. cout<<endl;
  73. }
  74. return 0;
  75. }
  76. void Add_Edge(int u,int v,int flow)
  77. {
  78. cnt++;
  79. Next[cnt]=Head[u];
  80. Head[u]=cnt;
  81. E[cnt].u=u;
  82. E[cnt].v=v;
  83. E[cnt].flow=flow;
  84. cnt++;
  85. Next[cnt]=Head[v];
  86. Head[v]=cnt;
  87. E[cnt].u=v;
  88. E[cnt].v=u;
  89. E[cnt].flow=0;
  90. }
  91. bool bfs()
  92. {
  93. memset(depth,-1,sizeof(depth));
  94. int h=1,t=0;
  95. Q[1]=0;
  96. depth[0]=1;
  97. do
  98. {
  99. t++;
  100. int u=Q[t];
  101. //cout<<u<<endl;
  102. for (int i=Head[u];i!=-1;i=Next[i])
  103. {
  104. int v=E[i].v;
  105. //cout<<v<<endl;
  106. if ((depth[v]==-1)&&(E[i].flow>0))
  107. {
  108. depth[v]=depth[u]+1;
  109. h++;
  110. Q[h]=v;
  111. }
  112. }
  113. }
  114. while (h!=t);
  115. if (depth[n+m+1]==-1)
  116. return 0;
  117. return 1;
  118. }
  119. int dfs(int u,int flow)
  120. {
  121. if (u==n+m+1)
  122. return flow;
  123. for (int &i=cur[u];i!=-1;i=Next[i])
  124. {
  125. int v=E[i].v;
  126. if ((depth[v]==depth[u]+1)&&(E[i].flow>0))
  127. {
  128. int di=dfs(v,min(flow,E[i].flow));
  129. if (di>0)
  130. {
  131. E[i].flow-=di;
  132. E[i^1].flow+=di;
  133. return di;
  134. }
  135. }
  136. }
  137. return 0;
  138. }

Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)的更多相关文章

  1. Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  2. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  3. [loj #6003]「网络流 24 题」魔术球 二分图最小路径覆盖,网络流

    #6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 ...

  4. liberOJ#6006. 「网络流 24 题」试题库 网络流, 输出方案

    #6006. 「网络流 24 题」试题库     题目描述 假设一个试题库中有 n nn 道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取 m mm 道题组成试卷.并要求 ...

  5. Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)

    Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...

  6. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

  7. Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流)

    Libre 6011 「网络流 24 题」运输问题 (网络流,最小费用最大流) Description W 公司有m个仓库和n个零售商店.第i个仓库有\(a_i\)个单位的货物:第j个零售商店需要\( ...

  8. Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)

    Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...

  9. Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流)

    Libre 6008 「网络流 24 题」餐巾计划 (网络流,最小费用最大流) Description 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. ...

随机推荐

  1. 云计算背后的秘密:NoSQL诞生的原因和优缺点

    转载收藏一篇对nosql讲解的比较全面的文章:http://blog.csdn.net/xlgen157387/article/details/47908797 这篇文章将和大家聊聊为什么NoSQL会 ...

  2. Android开发——RecyclerView特性以及基本使用方法(二)

    0.  前言 随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用.但显然并不能说RecyclerView就一定优于ListView,而是应该根据 ...

  3. 蒙提霍尔游戏 python 模拟

    本文使用蒙特卡罗方法验证蒙提霍尔游戏的结论. 以下代码,本人原创! 完整代码 import random # 蒙提霍尔游戏 def play_game(strategy='nonchange'): # ...

  4. python 连接 hive 的 HiveServer2 的配置坑

    环境: hadoop 2.7.6 hive 2.3.4 Hive 的 thirft 启动: hadoop 单机或者集群需要: 启动 webhdfs 修改 hadoop 的代理用户 <proper ...

  5. 从头到尾谈一下HTTPS

    引言 “你能谈一下HTTPS吗?” “一种比HTTP安全的协议.” “...” 如果面试这样说的话那差不多就gg了,其实HTTPS要展开回答的话内容还挺丰富的.本篇文章详细介绍了HTTPS是什么.为什 ...

  6. 高可用Kubernetes集群-15. 部署Kubernetes集群统一日志管理

    参考文档: Github:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/fluentd-elasticsear ...

  7. FUNMVP:几张图看懂区块链技术到底是什么?(转载)

    几张图看懂区块链技术到底是什么? 本文转载自:http://www.cnblogs.com/behindman/p/8873191.html “区块链”的概念可以说是异常火爆,好像互联网金融峰会上没人 ...

  8. Scrum Meeting day 1

    第一次会议,在这一次的会议中,明确了任务目标,并将任务进行合理分配,并且规划了整个任务的初步计划. No_00:分工情况 姓名 分工   崔强      PM 杜正远 主力工程师 王嘉豪 主力工程师 ...

  9. LeetCode-----算法448.找到所有数组中消失的数字

    题目: 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现在数组中的数字. ...

  10. Hadoop 4 MapReduce

    对单词个数统计的MapReduce的案例 Mapper类: package main.java.worldClient; import java.io.IOException; import org. ...