Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
Description
W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={ I1, I2,…,In }。实验Ej 需要用到的仪器是I的子集Rj∈I。 配置仪器Ik 的费用为ck 美元。实验Ej 的赞助商已同意为该实验结果支付pj 美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
Input
第1行有2个正整数m和n(m,n <= 100)。m是实验数,n是仪器数。
接下来的m行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的n个数是配置每个仪器的费用。
Output
第1行是实验编号;第2行是仪器编号;最后一行是净收益。
Sample Input
2 3
10 1 2
25 2 3
5 6 7
Sample Output
1 2
1 2 3
17
Http
Luogu:https://www.luogu.org/problem/show?pid=2762
Libre:https://loj.ac/problem/6001
Source
网络流,最大流
解决思路
这道题要把其转换到网络流模型上不是很好理解。
首先我们来看一看构图
对于每一个实验,从源点到实验连一条流量为赞助商支付的钱的边;对于每一个仪器,从仪器到汇点连一条流量为仪器花费的边。对于每一个实验所需要的仪器,在实验与仪器之间连一条流量无穷大的边。在这张图上跑一边最大流,就可以得到最小的花费,再用总赞助商的支付钱减去这个花费即可。
为什么这样是对的呢?
从源点到实验的边保证了赞助商资助该实验不会超过赞助商的钱,而从仪器到汇点的边则保证了仪器最多只会花费掉这么多的钱
那么最后如何统计答案呢?
由于我们使用的是Dinic求最大流,那么我们可以直接借助层次图的depth数组来求解。因为最后要选取的实验必须是盈利的,所以从源点到盈利的实验的边一定一不满流的,那么也就是说在最后一遍bfs中一定会分配深度,那么我们只要找出depth不为0的实验即可。
同时,由于如果选择做某个实验就要花费其所有需要的仪器,我们可以在求出选择的实验的同时标记出要选择的仪器,最后再输出即可。
另:关于Dinic算法,请移步我的这篇文章
注:Libre的字符串读入似乎有些问题,容易出现RE
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=1000;
const int maxM=maxN*maxN*4;
const int inf=147483647;
class Edge
{
public:
int 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[maxM];
bool chose[maxN];//标记某个仪器是否被选择
char str[maxM];//读入时要用到的字符串
void Add_Edge(int u,int v,int flow);
bool bfs();
int dfs(int u,int flow);
int main()
{
int sum=0;
memset(Head,-1,sizeof(Head));
scanf("%d%d",&m,&n);
char ch=getchar();
while (ch!='\n')
ch=getchar();
for(int i=1;i<=m;++i)
{
int v;
scanf("%d",&v);
Add_Edge(0,i,v);//连接源点与实验
sum+=v;
memset(str,0,sizeof(str));
cin.getline(str,maxM);
int j=0;
while(sscanf(str+j,"%d",&v)==1)//注意这里的读入
{
if(!v)
j++;
else
Add_Edge(i,v+m,inf);//连接实验与仪器
while(v)
v/=10,j++;
j++;
}
}
/*
for (int i=1;i<=m;i++)//这是原来的字符串读入,会RE,有时还WA
{
int v;
scanf("%d",&v);
sum+=v;
Add_Edge(0,i,v);
ch=getchar();
do
{
while (((ch>'9')||(ch<'0'))&&(ch!='\n'))
ch=getchar();
if (ch=='\n')
break;
v=0;
while ((ch>='0')&&(ch<='9'))
{
v=v*10+ch-48;
ch=getchar();
}
///mcnt++;
Add_Edge(i,v+m,inf);
}
while (1);
}*/
for (int i=1;i<=n;i++)
{
int v;
scanf("%d",&v);
Add_Edge(i+m,n+m+1,v);//连接仪器与汇点
}
int Flow=0;
while (bfs())//Dinic
{
for (int i=0;i<=n+m+1;i++)
cur[i]=Head[i];
while (int di=dfs(0,inf))
Flow+=di;
}
memset(chose,0,sizeof(chose));
for (int i=1;i<=m;i++)//找出选择的实验
if (depth[i]!=-1)
{
printf("%d ",i);
for (int j=Head[i];j!=-1;j=Next[j])//同时标记要选择的仪器
chose[E[j].v-m]=1;
}
cout<<endl;
for (int i=1;i<=n;i++)
if (chose[i]==1)
printf("%d ",i);
cout<<endl;
cout<<sum-Flow<<endl;
return 0;
}
void Add_Edge(int u,int v,int flow)//添加边
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].v=v;
E[cnt].flow=flow;
cnt++;
Next[cnt]=Head[v];
Head[v]=cnt;
E[cnt].v=u;
E[cnt].flow=0;
return;
}
bool bfs()//构建层次图
{
memset(depth,-1,sizeof(depth));
int h=1,t=0;
Q[1]=0;
depth[0]=1;
do
{
t++;
int u=Q[t];
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((E[i].flow>0)&&(depth[v]==-1))
{
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 ((E[i].flow>0)&&(depth[v]==depth[u]+1))
{
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;
}
Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)的更多相关文章
- LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图
#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...
- LOJ6001 - 「网络流 24 题」太空飞行计划
原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...
- Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流)
Libre 6013 「网络流 24 题」负载平衡 (网络流,最小费用最大流) Description G 公司有n 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使n ...
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)
Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...
- Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)
Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...
- Libre 6003 「网络流 24 题」魔术球 (网络流,最大流)
Libre 6003 「网络流 24 题」魔术球 (网络流,最大流) Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只 ...
- LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题
#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- 【刷题】LOJ 6001 「网络流 24 题」太空飞行计划
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 \(E = \{ E_1, E_2, \cdots, E_m ...
- LibreOJ #6001. 「网络流 24 题」太空飞行计划
\(\quad\) 与网络流有关的最值有三个:最大流,最小费用,最小割.这道题是最小割.想了好久,终于想明白最小割应该怎么用. \(\quad\) 先找出矛盾的事物.在这道题中,两件事是矛盾的:做实验 ...
随机推荐
- 2017-2018 Exp7 网络欺诈技术防范 20155214
目录 Exp7 网络欺诈技术防范 实验内容 信息收集 知识点 Exp7 网络欺诈技术防范 实验内容 实验环境 主机 Kali 靶机 Windows 10 实验工具 平台 Metaploit 信息收集 ...
- 20155232《网络对抗》Exp4 恶意代码分析
20155232<网络对抗>Exp4 恶意代码分析 1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门 ...
- 20155318 《网络攻防》Exp3 免杀原理与实践
20155318 <网络攻防>Exp3 免杀原理与实践 基础问题 杀软是如何检测出恶意代码的? 基于特征来检测:恶意代码中一般会有一段有较明显特征的代码也就是特征码,如果杀毒软件检测到有程 ...
- POJ1094——拓扑排序和它的唯一性
比较模板的topological-sort题,关键在于每个元素都严格存在唯一的大小关系,而一般的拓扑排序只给出一个可能解,这就需要每趟排序的过程中监视它是不是总坚持一条唯一的路径. 算法导论里面的拓扑 ...
- 将WebService部署到 SharePoint 2010 gac 缓存中,并用Log4Net记录日志到数据库
最近做了一个sharePoint项目,需要实现的功能是,第三方网站访问我们sharePoint中的数据,通过Webservice方式实现文件的上传和下载. 于是代码工作完成了之后,本地调试没什么问题, ...
- 【Beta阶段】第一次Scrum Meeting!
本次会议为第一次Scrum Meeting会议~ 会议时长:20分 会议地点:依旧是7公寓1楼会客室 昨日任务一览 明日任务一览 刘乾 预定任务:(未完成)#128 学习如何在Github上自动构 ...
- Linux内核分析——第一周学习笔记
20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 第一节 存储程序计算机工作模型 1.冯诺依曼体系结构:即具有存储程序的计算机体系结构.目前大多数拥有计算和存储功能的设备(智能 ...
- Day Five
站立式会议 站立式会议内容总结 442 今天:编写具体计划的界面 遇到的问题:相对布局.绝对布局理解不够深刻 明天:完成设定计划时间的功能 331 今天:添加书籍/计划按钮,添加书籍时有一个文件选择 ...
- (第三周)使用visual studio 2015进行单元测试
Microsoft visual studio是目前最流行的windows平台应用程序的集成开发环境.最新版本为 Visual Studio 2015 .Visual Studio 2015 包含许多 ...
- Linux命令常用
数据库:查看日志 vim /var/log/mysqld.log