题解:线性规划与网络流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]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...
随机推荐
- JAVA中常用的异常处理情况
1.java.lang.nullpointerexception程序遇上空指针 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者 ...
- 吴裕雄--天生自然深度学习TensorBoard可视化:监控指标可视化
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # 1. 生成变量监控信息并定义生 ...
- android studio 3.2 查看Deveice Monitor
View菜单下面的 Tool Windows 下面的 Devecie File Explorer
- Java之多线程方式一(继承Thread类)
/** * 多线程的创建,方式一:继承于Thread类 * 1. 创建一个继承于Thread类的子类 * 2. 重写Thread类的run() --> 将此线程执行的操作声明在run()中 * ...
- tensroflow中如何计算特征图的输出及padding大小
根据tensorflow中的conv2d函数,我们先定义几个基本符号 1.输入矩阵 W×W,这里只考虑输入宽高相等的情况,如果不相等,推导方法一样,不多解释. 2.filter矩阵 F×F,卷积核 3 ...
- fread 和fgets 函数的使用
两个函数都是对FILE *fp 文件进行读取信息,fgets是每次读取一行,fread是一下子读完所有的文件内容. //一.fread的使用 FILE *fp; int nread; ] fp = f ...
- redis安装以及主从复制完整版
redis安装以及主从复制完整版redis版本:redis-3.2.11主从复制模式:master--> slave1--> slave2 master:10.10.11.32 slave ...
- OpenCV On Android环境配置最新&最全指南(Android Studio篇)
本文是从本人简书上搬运而来,属本人原创,如有转载,请注明出处:http://www.jianshu.com/p/6e16c0429044 简介 本文是<OpenCV On Android环境配置 ...
- Vue环境搭建-项目的创建-启动生命周期-组件的封装及应用
vue项目环境的搭建 """ node >>> python:node是用c++编写用来运行js代码的 npm(cnpm) >>> p ...
- sin之舞---蓝桥杯练习
问题描述 最近FJ为他的奶牛们开设了数学分析课,FJ知道若要学好这门课,必须有一个好的三角函数基本功.所以他准备和奶牛们做一个“Sine之舞”的游戏,寓教于乐,提高奶牛们的计算能力. 不妨设 An=s ...