P2762 太空飞行计划问题
经典的最大权闭合子图问题
实验有正的价值,仪器的价值为负
为了实验我们必须选择相应的仪器
所以从 S 连向实验,边权为实验的价值
实验与相应仪器之间连边,边权为 INF
仪器连向 T 边权为仪器的价格
解释:
首先最大权闭合子图就是要求在一个图中求出一个联通子图
该子图没有出边能到达非子图的其他点(闭合)
且权值最大
根据我们刚才的建图方式,S 到正权值的点连边,边权为点权,负权值点连向 T,边权为点权绝对值
点之间根据依赖关系连边,边权INF
如果我们搞一个最小割,考虑最小割的实际意义
显然只会割从 S 到实验的边和从仪器到 T 的边
如果割的是从 S 到实验的边则相当于我们放弃了此实验从而可以不选择此实验需要的仪器,要扣去实验的价值
如果割的是从仪器到 T 的边则向当于我们为了某些实验而选择了此仪器,要扣去仪器的价值
那么最大收益就是实验总价值(包括没进行的实验)减去最小割,显然减最小割是最优的方案,因为如果还有流量那么说明有实验还有仪器没得到
那么还要继续考虑放弃实验或购买仪器
最后求出最大收益还不够,还要具体到实验和仪器
发现数据其实不大
所以枚举仪器,每次把此仪器的价格调成 0,如果跑完最小割发现最终收益恰好多了此仪器的价格则说明此仪器有被选择
然后根据选择的仪器就可以知道哪些实验有被进行
因为读入十分毒瘤,所以要稍微注意一下
我读入用快读加了个特判就解决了
具体看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
bool flag;//flag用来特判是否换行
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
if(ch=='\n') flag=;//如果有换行flag=1
return x*f;
}
const int N=4e5+,INF=1e9+;
int fir[N],from[N<<],to[N<<],val[N<<],cntt,Fir[N];
inline void add(int a,int b,int c)
{
from[++cntt]=fir[a]; fir[a]=cntt;
to[cntt]=b; val[cntt]=c;
from[++cntt]=fir[b]; fir[b]=cntt;
to[cntt]=a; val[cntt]=;
}
int n,m,S,T;
int ans;
int dep[N];
queue <int> q;
int BFS()
{
for(int i=;i<=T;i++) dep[i]=;
q.push(S); dep[S]=;
while(!q.empty())
{
int x=q.front(); q.pop();
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(dep[v]||!val[i]) continue;
q.push(v); dep[v]=dep[x]+;
}
}
for(int i=;i<=T;i++) Fir[i]=fir[i];
return dep[T];
}
int dfs(int x,int mif)
{
if(x==T||!mif) return mif;
int fl=,res=;
for(int i=Fir[x];i;i=from[i])
{
Fir[x]=i; int &v=to[i]; if(dep[v]!=dep[x]+) continue;
if( res=dfs(v,min(mif,val[i])) )
{
fl+=res; mif-=res;
val[i]-=res; val[i^]+=res;
if(!mif) break;
}
}
return fl;
}
int Val[N],Cst[N];//Val是实验价值,Cst是仪器花费
vector <int> ned[N];//存实验需要的仪器编号
int solve(int P)//枚举仪器求最大收益
{
memset(fir,,sizeof(fir)); cntt=;//记得初始化
int res=;
for(int i=;i<=n;i++)
{
add(S,i,Val[i]);
res+=Val[i];
int len=ned[i].size();
for(int j=;j<len;j++)
add(i,n+ned[i][j],INF);
}
for(int i=;i<=m;i++)
if(i!=P) add(n+i,T,Cst[i]);//建图不解释
while(BFS()) res-=dfs(S,INF);
return res;//返回最大收益
}
bool vis[N];//判断仪器是否购买
int main()
{
int a;
n=read(),m=read();
S=n+m+; T=n+m+;
for(int i=;i<=n;i++)
{
flag=; Val[i]=read();
while(!flag)//判断是否换行
ned[i].push_back(read());
}
for(int i=;i<=m;i++) Cst[i]=read();
ans=solve();//先求一波最大收益
for(int i=;i<=m;i++)//枚举仪器
{
int p=solve(i);
if(p-ans==Cst[i]) vis[i]=;//注意要恰好等于
}
for(int i=;i<=n;i++)//然后根据仪器求出实验是否进行
{
int P=,len=ned[i].size();
for(int j=;j<len;j++) P&=vis[ned[i][j]];
if(P) printf("%d ",i);
}
printf("\n");
for(int i=;i<=m;i++) if(vis[i]) printf("%d ",i);
printf("\n");
printf("%d",ans);
return ;
}
P2762 太空飞行计划问题的更多相关文章
- 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码
洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...
- 网络流24题:P2762 太空飞行计划问题
P2762 太空飞行计划问题 题目背景 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,E ...
- P2762 太空飞行计划问题(网络流24题之一)
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- P2762 太空飞行计划问题 网络流
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- 【luogu P2762 太空飞行计划问题】 题解
题目链接:https://www.luogu.org/problemnew/show/P2762 算是拍照那个题的加强下. 输入真的很毒瘤.(都这么说但好像我的过了?) #include <qu ...
- 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)
https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...
- 洛谷 - P2762 - 太空飞行计划问题 - 最小割
https://www.luogu.org/problemnew/solution/P2762 最小割对应的点,在最后一次更新中dinic的bfs会把他的dep重置掉.所以可以根据这个性质复原最小割. ...
- P2762 太空飞行计划问题 最大权闭合子图
link:https://www.luogu.org/problemnew/show/P2762 题意 承担实验赚钱,但是要花去对应仪器的费用,仪器可能共用.求最大的收益和对应的选择方案. 思路 这道 ...
- luogu P2762 太空飞行计划问题
好像是最大权闭合图,也就是最大流最小割啦,找出最大流的路径输出,这题如何建模呢,一样的先设源点和汇点,源点向每个计划连capacity为赞助数的边,每个计划连相应装置capacity为无穷的边,每个装 ...
- 洛谷 [P2762] 太空飞行计划问题
最大权闭合子图 胡伯涛论文真是个好东西.jpg 求一个有向图的最大权闭合子图,常应用于有先决条件的最优化问题中 将所有正权点与源点相连,容量为点权; 将所有负权点与汇点相连,容量为点权的相反数; 将原 ...
随机推荐
- C++——多线程
1.多进程和多线程:进程是一个总任务,一个进程可能包含多个线程. 2.并行和并发: 并发的关键是你有处理多个任务的能力,不一定要同时. 并行的关键是你有同时处理多个任务的能力. 3.共享数据的管理和线 ...
- Luogu 5043 【模板】树同构([BJOI2015]树的同构)
BZOJ 4337 简单记录一种树哈希的方法:以$x$为根的子树的哈希值为$\sum_{y \in son(x)}f_y*base_i$,$f_y$表示以$y$为根的树的哈希值,其中$i$表示$f_y ...
- Django框架 之 form组件的钩子
Django框架 之 form组件的钩子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3 ...
- GCC 4.7相对4.6.x的改进点
原文:http://www.iteye.com/news/24628针对C的功能改进: 支持ISO C11标准中的更多特性.除了之前的-std=c1x和-std=gnu1x选项外,GCC现在还支持-s ...
- Java 数据结构之数组
public class Arrays { //创建一个Integer空数组 public static Integer[] player=null; //添加球员号码 pri ...
- Ext JS v2.3.0 Ext.grid.ColumnModel renderer Record 获取列值
场景:设置某一列的值,但是需要获取其他列的值 {"header": '<s:property value="name" />', "wid ...
- 用ActionBar的ActionProvider的时候报错:cannot be cast to android.view.ActionProvider
在用ActionBar的自定义ActionProvider的时候有时候会遇到以下的报错:
- .net core webapi 文件上传在 Swagger 文档中的有好提示处理
前提: 需要nuget Swashbuckle.AspNetCore 我暂时用的是 4.01 最新版本: 描述:解决 .net core webapi 上传文件使用的是 IFormFile,在S ...
- Unity5.5.2 CD旋转 顺时针逆时针
UGUI 下 Sprite_CD 在Inspector下 Image(Script) 下 Clock wise 勾选 决定 CD是顺时针还是逆时针 默认是顺时针 勾选则为逆时针
- I-team 博客全文检索 Elasticsearch 实战
一直觉得博客缺点东西,最近还是发现了,当博客慢慢多起来的时候想要找一篇之前写的博客很是麻烦,于是作为后端开发的楼主觉得自己动手丰衣足食,也就有了这次博客全文检索功能Elasticsearch实战,这里 ...