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 题」太空飞行计划 (网络流,最大流)的更多相关文章

  1. LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

    #6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...

  2. LOJ6001 - 「网络流 24 题」太空飞行计划

    原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...

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

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

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

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

  5. Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)

    Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...

  6. Libre 6003 「网络流 24 题」魔术球 (网络流,最大流)

    Libre 6003 「网络流 24 题」魔术球 (网络流,最大流) Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只 ...

  7. LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

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

  8. 【刷题】LOJ 6001 「网络流 24 题」太空飞行计划

    题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 \(E = \{ E_1, E_2, \cdots, E_m ...

  9. LibreOJ #6001. 「网络流 24 题」太空飞行计划

    \(\quad\) 与网络流有关的最值有三个:最大流,最小费用,最小割.这道题是最小割.想了好久,终于想明白最小割应该怎么用. \(\quad\) 先找出矛盾的事物.在这道题中,两件事是矛盾的:做实验 ...

随机推荐

  1. 20155311《网络对抗》PC平台逆向破解(二)

    20155311<网络对抗>PC平台逆向破解(二) shellcode注入 什么是shellcode? shellcode是一段代码,溢出后,执行这段代码能开启系统shell. 前期准备- ...

  2. 20155323刘威良《网络对抗》Exp5 MSF基础应用

    20155323刘威良<网络对抗>Exp5 MSF基础应用 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 1.1一个主动攻击实 ...

  3. 腾讯云CVM服务器怎么建网站

    腾讯云云服务器CVM站在用户的角度看就相当于一台计算机,虽然实际上它是一个虚拟服务器,是一个大的云端服务器集群虚拟出来的一个虚拟服务器,在使用上直接当做一个实际的服务器即可.那么,对于一个新手菜鸟来说 ...

  4. Dynamics CRM Online Administrator password reset

    道道还挺多,好好看看 Dynamics CRM Online Administrator password reset

  5. Mvc4_@Styles.Render提高性能

    在页面上可以用@Styles.Render("~/Content/css") 来加载css 首先要在App_Start 里面BundleConfig.cs 文件里面 添加要包含的c ...

  6. ECS centos7 使用外部邮件服务商的465加密端口

    ECS centos7 使用外部邮件服务商的465加密端口发送邮件. 1.修改/etc/mail.rc 文件中添加以下的 set smtp="smtps://smtp.163.com:465 ...

  7. Mysql的基本操作(一)增、删、改

    创建/增加(create创建,alter字段操作,insert插入) 创建数据库 create database 数据库名称 charset=utf8; # 例: create database te ...

  8. (功能篇)回顾Bug管理系统Mantis优化改造经历

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  9. Estimation And Gain

    Estimation: Almost every is spent on ergod the text and build the dictionary. Gains: I have never us ...

  10. SCRUM 12.03

    第二轮迭代从今天起正式开始了.12月3日,我们举行了一次组会. 第一轮迭代结束时,我们意识到第二轮迭代需要实现的功能主要如下: 在下次迭代的时候实现对多个网站的信息进行比较取最优惠的选择,目前我们劲针 ...