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 题意 承担实验赚钱,但是要花去对应仪器的费用,仪器可能共用.求最大的收益和对应的选择方案. 思路 这道 ...
随机推荐
- Supervisord进程管家
Supervisord进程管家 Supervisord是一个守护进程的工具,当进程意外终止或服务器掉电起来后,希望进程能够自动运行,supervisord可以很好的为我们做这件事情.同时supervi ...
- 【JDBC核心】实现 CRUD 操作
实现 CRUD 操作 操作和访问数据库 数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果.其实一个数据库连接就是一个 Socket 连接. java.sql 包中有 ...
- 【剑指 Offer】06.从尾到头打印链表
题目描述 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2,3,1] 限制: 0 <= 链表长度 <= 10 ...
- appium识别工具介绍
- 3610:20140827:161308.483 No active checks on server: host [192.168.1.10] not found
3610:20140827:161308.483 No active checks on server: host [192.168.1.10] not found
- 【VNC】vnc安装oracle的时候不显示图形化界面
背景: 在虚拟机搭建了一个环境,准备安装oracle.但是环境都配置完成后,执行./runInstaller的时候,没有界面显示,只显示下面的界面 多次尝试后,发现,还是这样,期初是因为没有配置DIS ...
- leetcode 93. Restore IP Addresses(DFS, 模拟)
题目链接 leetcode 93. Restore IP Addresses 题意 给定一段序列,判断可能组成ip数的所有可能集合 思路 可以采用模拟或者DFS的想法,把总的ip数分成四段,每段判断是 ...
- centos7虚拟机开启端口后 外部不能访问的问题
转载 https://blog.csdn.net/u012045045/article/details/104219823 虚拟机新开了5005端口,系统内部是显示开了的(wget 192.168.4 ...
- Pku1236 Network of Schools
题目描述 n个学校构成一个有向图,通过m条边连接,一:问至少向图中多少个学校投放软件,可以使得所有学校直接或者间接的通过边(假设存在边(u,v),则向u投放v可以得到,而向v投放u不能通过v直接得到) ...
- python生成器 递归
生成器 生成器:只要函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器 生成器就是迭代器 yield的功能 1.yield为我们提供了一种自定义迭 ...