P2762 太空飞行计划问题 (最小割)
题意:n个实验 每个实验可获利ai元 做每个实验需要几个仪器
购买每个仪器有不同的花费 不同实验可能会用到同一个仪器 只用购买一次 求最大收益
题解:............................................
先讲玄学建图吧
从s向每个实验连权值为仪器收益的边
从每个仪器向t连权值仪器花费的边
实验与仪器之间连INF的边
答案等于所有实验的收益 减去 (最大流=最小割)
感性的理解一下.. 你已经获得了实验的收益了 如果当前存在一条s->t的路径 那么就表示你这个实验 还欠缺着某个仪器没买
因为把仪器割掉的含义是买这个仪器 所以才会减去花费
如果把实验割掉了 那么显然就是不做这个实验
然后输出方案也学到一个trick 就是在最后一次bfs的时候 如果当前点跑不到 dis = INF 那么意味着到这个点的边权被减为0了 流满了 就是这个点被割掉了
在这个题里被割掉了就意味着 选择做实验 买仪器
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f; int n, m, s, t, maxflow, cnt;
struct node {
int to, nex, val;
}E[100005];
int head[105];
int cur[105]; void addedge(int x, int y, int va) {
E[++cnt].to = y; E[cnt].nex = head[x]; head[x] = cnt; E[cnt].val = va;
E[++cnt].to = x; E[cnt].nex = head[y]; head[y] = cnt; E[cnt].val = 0;
} int dep[105];
int inque[105];
bool bfs() {
for(int i = 1; i <= t; i++) dep[i] = INF, inque[i] = 0, cur[i] = head[i];
queue<int> que;
que.push(s);
dep[s] = 0, inque[s] = 1; while(!que.empty()) {
int u = que.front();
que.pop();
inque[u] = 0; for(int i = head[u]; i; i = E[i].nex) {
int v = E[i].to;
if(E[i].val && dep[v] > dep[u] + 1) {
dep[v] = dep[u] + 1;
if(!inque[v]) {
que.push(v);
inque[v] = 1;
}
}
}
}
return dep[t] != INF;
} int vis;
int dfs(int x, int flow) {
if(x == t) {
maxflow += flow;
vis = 1;
return flow;
} int rflow = 0;
int used = 0;
for(int i = cur[x]; i; i = E[i].nex) {
cur[x] = i;
int v = E[i].to;
if(E[i].val && dep[v] == dep[x] + 1) {
if(rflow = dfs(v, min(flow - used, E[i].val))) {
used += rflow;
E[i].val -= rflow;
E[i ^ 1].val += rflow;
if(used == flow) break;
}
}
}
return used;
} void dinic() {
maxflow = 0;
while(bfs()) {
vis = 1;
while(vis) {
vis = 0;
dfs(s, INF);
}
}
} int p[55];
int c[55];
int ans[55];
int viss[55];
int ned[55][55];
char tools[10000]; int main() {
int sum = 0;
scanf("%d%d", &n, &m);
s = n + m + 1;
t = s + 1;
cnt = 1;
int ulen; for(int i = 1; i <= n; i++) {
scanf("%d", &p[i]);
sum += p[i];
addedge(s, i, p[i]); memset(tools, 0, sizeof(tools));
cin.getline(tools, 10000);
ulen = 0;
int num;
while(sscanf(tools + ulen, "%d", &num) == 1) {
ned[i][num] = 1;
addedge(i, n + num, INF); if(num == 0) ulen++;
else {
while(num) {
num /= 10;
ulen++;
}
}
ulen++;
} }
for(int i = 1; i <= m; i++) scanf("%d", &c[i]);
for(int i = 1; i <= m; i++) addedge(n + i, t, c[i]);
dinic(); for(int i = 1; i <= m; i++) {
for(int j = head[i + n]; j; j = E[j].nex) {
int v = E[j].to;
if(v == t) {
if(E[j].val == 0) viss[i] = 1;
break;
}
}
} for(int i = 1; i <= n; i++) {
if(dep[i] != INF) printf("%d ", i);
}
puts(""); for(int i = 1; i <= m; i++) {
if(dep[i + n] != INF) printf("%d ", i);
}
puts("");
printf("%d\n", sum - maxflow);
return 0;
}
P2762 太空飞行计划问题 (最小割)的更多相关文章
- 洛谷 - P2762 - 太空飞行计划问题 - 最小割
https://www.luogu.org/problemnew/solution/P2762 最小割对应的点,在最后一次更新中dinic的bfs会把他的dep重置掉.所以可以根据这个性质复原最小割. ...
- P2762 [网络流24题]太空飞行计划问题(最小割)
地址 最大权闭合子图裸题,不说了吧,求方案就是把s集遍历一遍. 错误记录:dfs那块忘判断残量了,11分×1. #include<cstdio> #include<iostream& ...
- 洛谷 P2762 太空飞行计划问题 P3410 拍照【最大权闭合子图】题解+代码
洛谷 P2762 太空飞行计划问题 P3410 拍照[最大权闭合子图]题解+代码 最大权闭合子图 定义: 如果对于一个点集合,其中任何一个点都不能到达此集合以外的点,这就叫做闭合子图.每个点都有一个权 ...
- 网络流24题:P2762 太空飞行计划问题
P2762 太空飞行计划问题 题目背景 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,E ...
- 洛谷 P4174 [NOI2006]最大获利 && 洛谷 P2762 太空飞行计划问题 (最大权闭合子图 && 最小割输出任意一组方案)
https://www.luogu.org/problemnew/show/P4174 最大权闭合子图的模板 每个通讯站建一个点,点权为-Pi:每个用户建一个点,点权为Ci,分别向Ai和Bi对应的点连 ...
- 洛谷P2762 太空飞行计划问题(最小割)
传送门 我们可以把实验放在左边,仪器放在右边,点有点权,然后连对应的有向边,就是求一个最大权闭合图,可以转化为最小割来做(关于这具体是个啥……可以百度胡伯涛<最小割模型在信息学竞赛中的应用> ...
- P2762 太空飞行计划问题(网络流24题之一)
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- P2762 太空飞行计划问题 网络流
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- P2762 太空飞行计划问题 最大权闭合子图
link:https://www.luogu.org/problemnew/show/P2762 题意 承担实验赚钱,但是要花去对应仪器的费用,仪器可能共用.求最大的收益和对应的选择方案. 思路 这道 ...
随机推荐
- 【JavaWeb】现代 JavaScript 教程
js_model_tutorial !!待更新 前言 现代 JavaScript 教程的学习笔记,它是一份不错的学习资源,感谢开源. 中文链接 基础 函数 代码示例 函数的声明方式 function ...
- 【C++】《C++ Primer 》第六章
第六章 函数 一.函数基础 函数定义:包括返回类型.函数名字和0个或者多个形参(parameter)组成的列表和函数体. 调用运算符:调用运算符的形式是一对圆括号 (),作用于一个表达式,该表达式是函 ...
- Java通过基姆拉尔森公式判断当前日期是不是工作日
基姆拉尔森公式 算法如下: 基姆拉尔森计算公式 W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7 在公式中d表示日期中的日数,m表示月份数,y表示年数. 注意:在公 ...
- Netty与NIO
初识Netty Netty是由JBoss提供的一个Java的开源框架,是GitHub上的独立项目. Netty是一个异步的,基于事件驱动的网络应用框架,用于快速开发高性能.高可靠的网络IO程序. Ne ...
- Spring框架之websocket源码完全解析
Spring框架之websocket源码完全解析 Spring框架从4.0版开始支持WebSocket,先简单介绍WebSocket协议(详细介绍参见"WebSocket协议中文版" ...
- K8s遇到问题解决思路
问题排查一 从describe去查找相应的deploy/pod/rs/svc [root@k8s-master ~]# kubectl describe po/nginx-f95d765f9-8b6b ...
- Linux删除文件后磁盘目录不释放
今天测试oracle数据库的时候,把表空间连带内容和数据文件一并删除了,但是删除之后,查看数据文件不存在了,但是目录的带下没有释放 SQL> drop tablespace users incl ...
- 3A的限流芯片PW1503
PW1503是超低RDS(ON)开关,具有可编程的电流限制,以保护电源于过电流和短路情况.它具有超温保护以及反向闭锁功能. PW1503采用薄型(1毫米)5针薄型SOT封装,提供可调版本. 特征 ...
- JavaScript小记
JavaScript小记 1. 简介 1. 语言描述 JavaScript 是一门跨平台.面向对象的弱类型动态脚本编程语言 JavaScript 是一门基于原型.函数先行的语言 JavaScript ...
- /bin/sh: cc: command not found
make的时候报错:/bin/sh: cc: command not found 解决: 1. sudo yum -y install gcc gcc-c++ libstdc++-devel 2. m ...