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求解最大流,可以参考我的这篇文章

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxN=2000;
const int maxM=maxN*maxN;
const int inf=2147483647; class Edge
{
public:
int u,v,flow;
}; int n,m;
int cnt=-1;
int Head[maxN];
int Next[maxM];
Edge E[maxM];
int depth[maxN];
int cur[maxN];
int Q[maxN]; void Add_Edge(int u,int v,int flow);
bool bfs();
int dfs(int u,int flow); int main()
{
memset(Head,-1,sizeof(Head));
int sum=0;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
{
int num;
scanf("%d",&num);
sum+=num;//统计总类型要求数量
Add_Edge(0,i,num);//连边源点到类型
}
for (int i=1;i<=m;i++)
{
int p;
scanf("%d",&p);
for (int j=1;j<=p;j++)
{
int u;
scanf("%d",&u);
Add_Edge(u,n+i,1);//连边类型到题目
}
Add_Edge(n+i,n+m+1,1);//连边题目到汇点
}
int Ans=0;//求解最大流
while (bfs())
{
for (int i=0;i<=n+m+1;i++)
cur[i]=Head[i];
while (int di=dfs(0,inf))
Ans+=di;
}
if (Ans<sum)//若最大流小于要求总数,则说明无解
{
cout<<"No Solution!"<<endl;
return 0;
}
for (int i=1;i<=n;i++)//有解,则输出一种方案
{
cout<<i<<": ";
for (int j=Head[i];j!=-1;j=Next[j])
{
int v=E[j].v;
if ((v>=n+1)&&(v<=n+m)&&(E[j].flow==0))
cout<<v-n<<" ";
}
cout<<endl;
}
return 0;
} void Add_Edge(int u,int v,int flow)
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].u=u;
E[cnt].v=v;
E[cnt].flow=flow; cnt++;
Next[cnt]=Head[v];
Head[v]=cnt;
E[cnt].u=v;
E[cnt].v=u;
E[cnt].flow=0;
} bool bfs()
{
memset(depth,-1,sizeof(depth));
int h=1,t=0;
Q[1]=0;
depth[0]=1;
do
{
t++;
int u=Q[t];
//cout<<u<<endl;
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
//cout<<v<<endl;
if ((depth[v]==-1)&&(E[i].flow>0))
{
depth[v]=depth[u]+1;
h++;
Q[h]=v;
}
}
}
while (h!=t);
if (depth[n+m+1]==-1)
return 0;
return 1;
} int dfs(int u,int flow)
{
if (u==n+m+1)
return flow;
for (int &i=cur[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((depth[v]==depth[u]+1)&&(E[i].flow>0))
{
int di=dfs(v,min(flow,E[i].flow));
if (di>0)
{
E[i].flow-=di;
E[i^1].flow+=di;
return di;
}
}
}
return 0;
}

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. WPF编程,自定义鼠标形状的一种方法。

    原文:WPF编程,自定义鼠标形状的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8727 ...

  2. Hadoop日记Day7---HDFS的WED端口

    HDFS 对外提供了可供访问的http server,开放了很多端口,下面介绍常用的几个端口(http://hadoop:……). 一.50070 端口,查看NameNode 状态,如图1.1所示. ...

  3. Linux下的openvpn配置 与 easy-rsa3的证书生成

    #注意:以下操作由服务端操作即可#PS:为什么我找不到var文件??============安装===============wget -O /etc/yum.repos.d/epel.repo ht ...

  4. eclipse 最最最常用快捷键

    使用eclipse这么久,发现其跟PS一样,使用一些快捷键会有效率很多. 至此总结出以下每次打开eclipse基本都会用上的快捷键. 不熟悉这些快捷键,在实际编程中有意识使用的话对以后编码很有帮助. ...

  5. HTML-JS 循环 函数 递归

    [循环结构的执行步骤] 1.声明循环变量 2.判断循环条件 3.执行循环体操作 4.更新循环变量 然后,循环执行2-4,直到条件不成立时,跳出循环. while循环()中的表达式,运算结果可以是各种类 ...

  6. centos7 源码部署LNMP

    一.环境 系统环境:centos 7.4 64位 Nginx:1.7.9 MySQL: 5.7.20 (二进制包) PHP:5.6.37 二.Ngin 安装 Nginx部署 yum install   ...

  7. Azure 基础:自定义 Table storage 查询条件

    本文是在 <Azure 基础:Table storage> 一文的基础上介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table s ...

  8. postman 断点

  9. 关于UGUI不拦截射线的方法

    起因:开发游戏,要在设置界面里给一个设置项添加一个东西解释这个项是干啥的,要求鼠标移到文字上的时候显示一个弹窗差不多的东西,见动图,鼠标移开会消失.但是当我移动鼠标到弹窗上的时候,UGUI会发射一根射 ...

  10. Go语言实现数据结构(一)单链表

    1.基本释义 2.结构体设计 3.基本方法设计 4.Main函数测试 1. 基本释义 线性表包含两种存储方法:顺序存储结构和链式存储结构,其中顺序表的缺点是不便插入与删除数据:接下来我们重点实现基于G ...