太空飞行计划问题

问题描述

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 太空飞行计划问题的更多相关文章

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

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

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

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

  3. Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)

    Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...

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

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

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

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

  6. [Cogs727] [网络流24题#2] 太空飞行计划 [网络流,最小割]

    建图:源点—(w[i])—>实验—(∞)—>仪器—(cost[i])—>汇点, 如果该实验造成收益,则仪器到汇点的边在最小割中, 如果该实验造成损失,则源点到实验的边在最小割中, 故 ...

  7. 【PowerOJ1737&网络流24题】太空飞行计划问题(最小割)

    题意: 思路: #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned in ...

  8. 【线性规划与网络流 24题】已完成(3道题因为某些奇怪的原因被抛弃了QAQ)

    写在前面:SDOI2016 Round1滚粗后蒟蒻开始做网络流来自我拯救(2016-04-11再过几天就要考先修课,现在做网络流24题貌似没什么用←退役节奏) 做的题目将附上日期,见证我龟速刷题. 1 ...

  9. 【题解】【网络流24题】航空路线问题 [P2770] [Loj6122]

    [题解][网络流24题]航空路线问题 [P2770] [Loj6122] 传送门:航空路线问题 \([P2770]\) \([Loj6122]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...

随机推荐

  1. 《Docekr入门学习篇》——Docker网络及数据卷

    Docker网络设置 默认情况下docker会创建一个桥接网卡[docker 0],docker有两种映射方式,一种是随机映射,一种是指定映射. 提示:生产场景一般不使用随机映射,但是随机映射的好处是 ...

  2. ServiceComb 集成 Shiro 实践|火影专场发布

    Shiro简介 Apache Shiro是一款功能强大.易用的轻量级开源Java安全框架,它主要提供认证.鉴权.加密和会话管理等功能.Spring Security可能是业界用的最广泛的安全框架,但是 ...

  3. 基于Guava实现的文件复制

    需求:现需要将文件D:\A\B\C\abc.txt进行一下操作 1.在文件夹D:\A\B\C下,没有以abc命名的文件夹则创建 2.将目标文件D:\A\B\C\abc.txt复制到abc下 实现代码: ...

  4. 吴裕雄--天生自然ShellX学习笔记:Shell 文件包含

    和其他语言一样,Shell 也可以包含外部脚本.这样可以很方便的封装一些公用的代码作为一个独立的文件. Shell 文件包含的语法格式如下: . filename # 注意点号(.)和文件名中间有一空 ...

  5. python3拆包详解

    对于可迭代对象,如元组.列表.字符串.集合.字典这些可迭代对象都可以被拆包,拆包是指将一个结构中的数据拆分为多个单独变量中.拆包的方式大致有两种,一种是以变量的方式来接收,另一种是用'*'号.下面先讲 ...

  6. 吴裕雄--天生自然 JAVA开发学习:接口

    [可见度] interface 接口名称 [extends 其他的接口名] { // 声明变量 // 抽象方法 } import java.lang.*; //引入包 public interface ...

  7. 吴裕雄--天生自然 PYTHON3开发学习:JSON 数据解析

    import json # Python 字典类型转换为 JSON 对象 data = { 'no' : 1, 'name' : 'Runoob', 'url' : 'http://www.runoo ...

  8. 【lca+输入】Attack on Alpha-Zet

    Attack on Alpha-Zet 题目描述 Space pirate Captain Krys has recently acquired a map of the artificial and ...

  9. 大厂面试题:今天复试百度PHP工程师

    今天下午来到北京百度科技园进行复试PHP工程师岗位. 面试官问了很多问题,我大概整理回忆下: 1.Redis秒杀实现? redis队列解决抢购高并发的原理: 在程序跟数据库之前呢我们可以利用redis ...

  10. CSS样式表-------第二章:选择器

    二 .选择器 内嵌.外部样式表的一般语法: 选择器 { 样式=值: 样式=值: 样式=值: ...... } 以下面html为例,了解区分一下各种样式的选择器 <head> <met ...