题解:线性规划与网络流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]\) [题目描述] 给出一张有向图,每个点(除了起点 \( ...
随机推荐
- spring-boot 如何加载rsources下面的自定义配置文件
spring-boot 如何加载resources下面的自定义配置文件 https://segmentfault.com/q/1010000006828771?_ea=1144561
- PAT甲级——1073 Scientific Notation (20分)
Scientific notation is the way that scientists easily handle very large numbers or very small number ...
- POJ 3273 Monthly Expense二分查找[最小化最大值问题]
POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...
- Djang_框架
- mysql Communications link failure Last packet sent to the server was X ms ago
想必大家在用MySQL时都会遇到连接超时的问题,如下图所示: 就是这个异常(com.mysql.jdbc.exceptions.jdbc4.Communication***ception:Commun ...
- 17.3.13--python编码问题
1----字符编码: 字符编码(英语:Character encoding).字集码是把字符集中的字符编码为指定集合中某一对象(例如:比特模式.自然数串行.8位组或者电脉冲),以便文本在计算机中存储和 ...
- 发布订阅--SQLServer复制需要有实际的服务器名称才能连接到服务器,请指定实际的服务器名
最近在学习SQL SERVER的高级复制技术的时候,遇到一个小问题,就是用本地SQL SERVER连接服务器的数据库时,在查看复制功能的发布服务器时,连接不上,弹出一个错误提示框架,如下: 原来在自己 ...
- Java和Mysql中的数据类型
1.mysql中的基本类型 1.整数: tinyint:1个字节 -128~127 smallint: 2个字节 -32768~32767 int : 4个字节 bigint: 8个字节 2 ...
- spring+mybatis配置多个数据源
http://www.cnblogs.com/lzrabbit/p/3750803.html
- 跟踪路由(tracert)及ping命令
由于最近学校网络不好,老是有问题,加上最近写了个数据展示系统,要部署到买的域名下,用到了这两个命令 首先,一台服务器,一台工作站,一个笔记本(我的,来测试ip是否通的) 服务器已经部署了三个网站(一个 ...