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 求一个有向图的最大权闭合子图,常应用于有先决条件的最优化问题中 将所有正权点与源点相连,容量为点权; 将所有负权点与汇点相连,容量为点权的相反数; 将原 ...
随机推荐
- 使用Layered Window遇到的一些问题及解决方法
1. 使用Layered Window需要设置 WS_EX_LAYERED 属性 2. Layered Window不能作为Child Window 3. 它也不能包含子窗口,为什么呢,因为它收不到 ...
- 41、Aspera下载安装运用
参考:http://www.so.com/linkm=aLVHG%2FgJT4HyuVeK4%2BxX2LMFvF6oTiTCaruHE20pwjRia7DmVI2hIVfmw%2BFNPczCtvX ...
- Entity Framework在不同数据库下的配置
http://blog.csdn.net/weiky626/article/details/17068593 http://blog.csdn.net/niewq/article/details/41 ...
- Gson 配置解析
之前项目用到了gson对json和Java类之间互转,现在将gson的配置总结一下. 首先,创建gson对象之间,建立gsonbuilder对象,并配置 // 不导出实体类中没有用@Expose注解的 ...
- [redis]redis-cluster搭建
1.概述: redis是一种工作在内存里no-sql的非关系型数据库,广泛应用于缓存需求,以减少大量的数据访问对数据库的压力,还很适合用来充当整个互联网架构中各级之间的cache 比如lvs的4层转发 ...
- Eclipse中连接数据库错误:com.microsoft.sqlserver.jdbc.SQLServerException: 之类的错误
原创 错误:org.apache.jasper.JasperException: Unable to compile class for JSP 原因是页面指令中 import="java. ...
- java代码实现顺序队列
java实现顺序队列 package xianxinTable; import java.util.ArrayList; import java.util.Iterator; import com.s ...
- 在iis7.5上部署asp.net mvc5
部署mvc5跟部署mvc4是一样的,唯一不同的是需要修改一下web.config的配置 在web.config中加入一下节点即可 <system.webServer> <module ...
- Echarts+WPF
C# using System; using System.Collections.Generic; using System.IO; using System.Linq; using System. ...
- angular 父组件调用子组件
import { Component, OnInit, ViewChild } from '@angular/core'; @Component({ selector: 'app-child', te ...