题解:线性规划与网络流24题 T2 太空飞行计划问题
太空飞行计划问题
问题描述
W教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}。实验Ej 需要用到的仪器是I的子集Rj ∈ I。配置仪器Ik的费用为ck美元。实验Ej 的赞助商已同意为该实验结果支付pj 美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
编程任务
对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
数据输入
由文件input.txt提供输入数据。文件第1行有2个正整数m和n。m是实验数,n是仪器数。接下来的m行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的n个数是配置每个仪器的费用。
结果输出
程序运行结束时,将最佳实验方案输出到文件output.txt中。第1行是实验编号;第2行是仪器编号;最后一行是净收益。
输入文件示例input.txt
2 3
10 1 2
25 2 3
5 6 7
输出文件示例output.txt
1 2
1 2 3
17
分析:
我们可以用最大权闭合图模型建图,把实验看作二分图的X集,仪器看作二分图的Y集。加个S,加个T,S向所有X集连边,边权为该实验的收入。所有仪器向T连边,边权为改仪器的花费。所有实验向其依赖的仪器连边,边权为inf
然后求最小割,答案就是所有实验收入之和Total - maxflow。
.......接下来让我们考虑一下为何能如此建图。
定义一个割划分出的S集为一个解,则割集容量之和为未选的实验的收入 + 被选的仪器的花费。这样Total – maxflow就代表被选的实验收入– 被选的仪器花费。
这样问题就转化成了最大化(Total – maxflow) ,也就是最小化maxflow。
So......you know.........
Code:
#include <cstdio>
#include <cstring>
using namespace std; const int inf = 1 << 30;
const int maxn = 1010;
const int maxm = 2020;
inline int min(int a,int b) {return a < b ? a : b;} int tot;
struct Edge
{
int v,w,nxt;
}e[maxm];
int head[maxn];
int d[maxn],q[maxn];
int sta,end; inline void addedge(int u,int v,int d)
{
e[tot].v = v,e[tot].w = d,e[tot].nxt = head[u],head[u] = tot ++;
e[tot].v = u,e[tot].w = 0,e[tot].nxt = head[v],head[v] = tot ++;
} inline int bfs()
{
memset(d,-1,sizeof(d));
int r = d[q[0] = sta] = 0;
for(int l = 0;l <= r;l ++)
for(int k = head[q[l]]; ~k ;k = e[k].nxt)
if(e[k].w && !~d[e[k].v])
d[q[++ r] = e[k].v] = d[q[l]] + 1;
return ~d[end];
} int find(int x,int low)
{
if(x == end) return low;
int a;
for(int k = head[x]; ~k ;k = e[k].nxt)
if(e[k].w && d[e[k].v] == d[x] + 1 && (a = find(e[k].v,min(low,e[k].w))))
{
e[k].w -= a;
e[k ^ 1].w += a;
return a;
}
return 0;
} int dinic()
{
int ret = 0,t;
while(bfs())
while(t = find(sta,inf)) ret += t;
return ret;
} bool bLineBreak;
void scan(int & n)
{
char c; n = 0; bLineBreak = 0;
while(c = getchar(),c < '0' || c > '9') if(c == '\n') bLineBreak = 1;
n = c - '0';
while(c = getchar(),(c >= '0' && c <= '9')) n = n * 10 + c - '0';
if(c == '\n') bLineBreak = 1;
} inline void debug_dinic()
{
int n,m;
scanf("%d%d",&n,&m);
sta = 0,end =1;
memset(head,-1,sizeof(head));
while(m --)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
printf(" %d \n",dinic());
} inline void debug_scan()
{
int n;
do
{
scan(n);
printf("%d\n",n);
} while(!bLineBreak);
} int experiment[maxn],vis[maxn]; int main()
{
int m,n,sum = 0;
sta = 0,end = 1;
scanf("%d%d",&m,&n);
memset(head,-1,sizeof(head));
for(int i = 0;i < m;i ++)
{
int val,id;
scanf("%d",&val);
addedge(sta,i + 2,val),sum += val;
do
{
scan(id);
addedge(i + 2,m + 1 + id,inf);
} while(!bLineBreak);
}
for(int i = 0;i < n;i ++)
{
int cost;
scanf("%d",&cost);
addedge(m + 2 + i,end,cost);
}
int ans = sum - dinic();
int cnt = 0;
for(int k = head[0]; ~k ;k = e[k].nxt) if(e[k].w)
{
int id = e[k].v;
experiment[cnt ++] = id;
printf("%d ",id - 1);
}
putchar('\n');
for(int i = 0;i < cnt;i ++)
{
for(int k = head[experiment[i]]; ~k ;k = e[k].nxt)
{
int v = e[k].v;
if(vis[v]) continue;
vis[v] = 1;
if(!e[head[v]].w) printf("%d ",e[k].v - 1 - m);
}
}
printf("\n%d",ans);
return 0;
}
题解:线性规划与网络流24题 T2 太空飞行计划问题的更多相关文章
- LOJ6001 - 「网络流 24 题」太空飞行计划
原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...
- LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图
#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...
- Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...
- 【刷题】LOJ 6001 「网络流 24 题」太空飞行计划
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 \(E = \{ E_1, E_2, \cdots, E_m ...
- LibreOJ #6001. 「网络流 24 题」太空飞行计划
\(\quad\) 与网络流有关的最值有三个:最大流,最小费用,最小割.这道题是最小割.想了好久,终于想明白最小割应该怎么用. \(\quad\) 先找出矛盾的事物.在这道题中,两件事是矛盾的:做实验 ...
- [Cogs727] [网络流24题#2] 太空飞行计划 [网络流,最小割]
建图:源点—(w[i])—>实验—(∞)—>仪器—(cost[i])—>汇点, 如果该实验造成收益,则仪器到汇点的边在最小割中, 如果该实验造成损失,则源点到实验的边在最小割中, 故 ...
- 【PowerOJ1737&网络流24题】太空飞行计划问题(最小割)
题意: 思路: #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned in ...
- 【线性规划与网络流 24题】已完成(3道题因为某些奇怪的原因被抛弃了QAQ)
写在前面:SDOI2016 Round1滚粗后蒟蒻开始做网络流来自我拯救(2016-04-11再过几天就要考先修课,现在做网络流24题貌似没什么用←退役节奏) 做的题目将附上日期,见证我龟速刷题. 1 ...
- 【题解】【网络流24题】航空路线问题 [P2770] [Loj6122]
[题解][网络流24题]航空路线问题 [P2770] [Loj6122] 传送门:航空路线问题 \([P2770]\) \([Loj6122]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...
随机推荐
- 启动zookeeper却没有进程
第一次: 没有jdk,安装好jdk就可以了 第二次: java的环境变量没配好,按照下图的配就行: Java_HOME和jre_HOME都是jdk的目录就行 最后两行不加试试,好像都没多大关系 应该是 ...
- 黑马_10 Lucene:全文检索
10 Lucene:01.全文检索基本介绍 10 Lucene:02.创建索引库和查询索引 10 Lucene:03.中文分析器 10 Lucene:04.索引库维护CURD
- kaggle——分销商产品未来销售情况预测
分销商产品未来销售情况预测 介绍 前面的几个实验中,都是根据提供的数据特征来构建模型,也就是说,数据集中会含有许多的特征列.本次将会介绍如何去处理另一种常见的数据,即时间序列数据.具体来说就是如何根据 ...
- 静态、动态cell区别
静态cell:cell数目固定不变,图片/文字固定不变(如qq设置列表可使用静态cell加载) 动态cell:cell数目较多,且图片/文字可能会发生变化(如应网络请求,淘宝列表中某个物品名称或者图片 ...
- 001-rabbitmq和haproxy结合
rabbitmq集群搭建 防火墙添加并重启 -A INPUT -p tcp -m multiport --dports 4369,25672,5672,15672 -j ACCEPT 安装 cd /u ...
- win10+CUDA9.0176、CUDNN7.6.0安装
在github上下载了一个文本分类的代码,包含了CNN.LSTM等分类模型,运行时说我的CUDA版本不行,我原来是9.1,让我安装9.0 然后开始卸载9.1啊,在此感谢博主:https://blog. ...
- LeetCode No.118,119,120
No.118 Generate 杨辉三角 题目 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行. 在杨辉三角中,每个数是它左上方和右上方的数的和. 示例 输入: 5 输出: [ ...
- spring cloud关于feign client的调用对象列表参数、设置header参数、多环境动态参数试配
spring cloud关于feign client的调用 1.有些场景接口参数需要传对象列表参数 2.有些场景接口设置设置权限等约定header参数 3.有些场景虽然用的是feign调用,但并不会走 ...
- java 计算一个月有多少天和多少周
import java.util.Calendar; /** * 功能概述:计算指定年月的天数和周数<br> */ public class Test{ public static voi ...
- VS制作dll、def文件的使用、dll加入工程使用
1.VS新建工程,在选项的时候,选择dll和空项目,保持干净的dll库: 创建完以后,添加头文件以及源文件. 2.将外部模块使用的接口导出: (1)函数导出: __declspec(dllexport ...