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 求一个有向图的最大权闭合子图,常应用于有先决条件的最优化问题中 将所有正权点与源点相连,容量为点权; 将所有负权点与汇点相连,容量为点权的相反数; 将原 ...
随机推荐
- CURL以 POST 请求链接的方式 初始化一个cURL会话来获取一个网页
/** *POST URL */ function posturl($URL,$data) { $ch = curl_init(); // 创建一个新cURL资源 curl_setopt($ch,CU ...
- SpringCloud03 Ribbon知识点、 Feign知识点、利用RestTemplate+Ribbon调用远程服务提供的资源、利用feign调用远程服务提供的资源、熔断
1 远程服务资源的调用 1.1 古老的套路 在微服务出现之前,所有的远程服务资源必须通过RestTemplate或者HttpClient进行:但是这两者仅仅实现了远程服务资源的调用,并未提供负载均衡实 ...
- c语言学习笔记 for循环的结构
其实感觉for循环没有while循环那么直白好理解. for(i=0;i<n;i++) { dosth(); } i=0是i的初始值. i<n是循环进行的条件. i++是每次循环要做的事情 ...
- tensor 维度 问题。
tf.argmax takes two arguments: input and dimension. example: tf.argmx(arr, dimension = 1). or tf.arg ...
- seconds
set_time_limit();//设置脚本运行时间为1秒
- Linux下的多线程下载工具mwget
之前在做项目的时候,遇到一个难题,需要一个多线程下载器,于是阴差阳错的看到了这款工具--mwget,之所以是阴差阳错,是因为mwget的多线程下载功能,并不是我们想要的多线程. wget大家都知道吧, ...
- Spring:配置文件
首先是bean.xml,配置所有的bean,一般也叫applicationContext.xml,应用程序上下文.示例: <?xml version="1.0" encodi ...
- delphi计算两个时间差
uses DateUtils; var S1, S2: string; T1, T2: TDateTime; D, H, M, S: Integer; Value: Int64; begin S1 : ...
- background-image属性的设置
对于图片,首先我们先想到是背景图片.因为我们许许多的装饰都是用背景图片来实现的.既然这样,那么就从CSS控制背景图片讲起吧.1.CSS控制背景图片: 对于一个网页,我们开始设计的时候,可能没有过 ...
- .Net高级面试宝典
1.in/exists/join 执行效率? 答:用法 select * from HK_UsersBasic where Users_ID in (select AccEmail from dbo ...