LibreOJ #6001. 「网络流 24 题」太空飞行计划
\(\quad\) 与网络流有关的最值有三个:最大流,最小费用,最小割。这道题是最小割。想了好久,终于想明白最小割应该怎么用。
\(\quad\) 先找出矛盾的事物。在这道题中,两件事是矛盾的:做实验 \(E_i\) 和不取\(E_i\) 要求的任意一个器材 \(I_j\)。上面的 \(5\) 个点依次表示做实验 \(E_1, E_2,...,E_5\),下面的 \(5\) 个点依次表示不取器材 \(I_1,I_2,...,I_5\)。(当然,实际情况中实验个数和器材个数不一定相等)

\(\quad\) 初始情况下,每个点都存在。其中,上面的 \(5\) 个点提供了 \(\sum_{i=1}^5p_i\) 的收益,下面的 \(5\) 个点提供了 \(0\) 的收益。这样的情况是非法的,因为它允许了一些矛盾的点存在。比方说,\(E_5\) 要求的器材有 \(I_3\),那么做 \(E_5\) 和不取 \(I_3\) 这两个点就是矛盾的,不能共存。

\(\quad\) 用连线来表示这种矛盾关系:有边相连的两个点是矛盾的。为了使情况合法,必须去掉一些点。去掉点有代价,比如,去掉不取 \(I_3\) 就是取 \(I_3\),代价为 \(I_3\) 的价格 \(c_3\);去掉做 \(E_2\) 的代价就是就是 \(E_2\) 的利润 \(p_2\)。我们的目的是使任意一条连线的两边都至多存在一个点,代价最小。换言之,要求通过删去一些点使得图的上半部分与下半部分不联通。

\(\quad\) 这就可以加上源点汇点,转换为图的最小割了。其中,\(t\) 与 \(E_i\) 的边的容量是去掉它的代价,即 \(p_i\);\(s\) 与 不取 \(I_i\) 的边的容量是去掉它的代价,即 \(c_i\)。其余边容量为 \(+\infty\)。

\(\quad\) 删去一条红边就代表删去对应的点;图的最小割就是最小代价。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
std::string str;
int it;
#define getchar() str[it++]
int read(void){
if(it == str.length())
return EOF;
int res = 0; char ch = getchar();
while(ch < '0' || ch > '9'){
if(it == str.length())
return EOF;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
res = res * 10 + ch - 48;
if(it == str.length())
return res;
ch = getchar();
}
return res;
}
const int MAXN = 3e2 + 19, MAXM = MAXN * MAXN + MAXN + MAXN, INF = 0x3f3f3f3f;
struct Edge{
int to, next, c;
}edge[MAXM];
int cnt = -1, head[MAXN];
inline void add(int from, int to, int c){
edge[++cnt].to = to;
edge[cnt].c = c;
edge[cnt].next = head[from];
head[from] = cnt;
}
int m, n;
int ans, c, p;
int dep[MAXN];
int bfs(void){
std::queue<int>q; q.push(0);
std::memset(dep, 0, sizeof dep); dep[0] = 1;
while(!q.empty()){
int node = q.front(); q.pop();
for(int i = head[node]; i != -1; i = edge[i].next)
if(!dep[edge[i].to] && edge[i].c)
dep[edge[i].to] = dep[node] + 1, q.push(edge[i].to);
}
return dep[n + m + 1];
}
inline int min(const int& a, const int& b){
return a < b ? a : b;
}
int dfs(int node, int flow){
if(node == n + m + 1 || !flow)
return flow;
int stream = 0, f;
for(int i = head[node]; i != -1; i = edge[i].next)
if(dep[edge[i].to] == dep[node] + 1 && (f = dfs(edge[i].to, min(flow, edge[i].c)))){
flow -= f, stream += f;
edge[i].c -= f, edge[i ^ 1].c += f;
if(!flow)
break;
}
return stream;
}
int dinic(void){
int flow = 0;
while(bfs())
flow += dfs(0, 0x3f3f3f3f);
return flow;
}
int main(){
std::memset(head, -1, sizeof head);
std::cin >> m >> n; std::getline(std::cin, str);
for(int i = 1; i <= m; ++i){
std::getline(std::cin, str); it = 0;
ans += (p = read());
add(0, i, p), add(i, 0, 0);
int u;
while((u = read()) != EOF)
add(i, m + u, INF), add(m + u, i, 0);
}
for(int i = 1; i <= n; ++i){
std::cin >> c;
add(m + i, m + n + 1, c), add(m + n + 1, m + i, 0);
}
ans -= dinic();
for(int i = 1; i <= m; ++i)
if(dep[i])
std::printf("%d ", i);
std::putchar('\n');
for(int i = 1; i <= n; ++i)
if(dep[m + i])
std::printf("%d ", i);
std::putchar('\n');
printf("%d\n", ans);
return 0;
}
行末空格真的烦...
LibreOJ #6001. 「网络流 24 题」太空飞行计划的更多相关文章
- LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图
#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...
- Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...
- 【刷题】LOJ 6001 「网络流 24 题」太空飞行计划
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 \(E = \{ E_1, E_2, \cdots, E_m ...
- LOJ6001 - 「网络流 24 题」太空飞行计划
原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...
- LibreOJ #6000. 「网络流 24 题」搭配飞行员
二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员 /* LibreOJ #6000. 「网络流 24 题」搭配飞行员 二分图最大匹配 Dinic最大流 + 当前弧优化 */ ...
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ...
- LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题
#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流
#6011. 「网络流 24 题」运输问题 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图
#6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
随机推荐
- java平衡二叉树AVL数
平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树 右旋:在插入二叉树的时候,根节点的右侧高 ...
- Python学习笔记(01)
参考书:<Python编程:从入门到实践> 还有其他 Chapter01 print print(a,b,sep="|") sep规定输出间的间隔 print(“Pyt ...
- jenkins介绍及部署tomcat环境、部署Maven项目及密码忘记修改
安装配置jenkins: jenkins安装方式一:war包 1.先安装tomcat将jenkins,war直接放到webapps目录下 2.通过java-jar jenkins.war --http ...
- 定义列表dl中标签 dt 与标签dd对齐方法,标签ul与标签li对齐
不定义css样式时(默认情况): 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...
- 在C中测试函数运行时间
#include <stdio.h> #include <time.h> #include <math.h> clock_t start, stop; //cloc ...
- OpenCV介绍
OpenCV 是什么 OpenCV是计算机视觉开源库,主要算法涉及图像处理和机器学习相关方法. 是 Intel 公司贡献出来的,俄罗斯工程师贡献大部分 C/C++ 代码 在多数图像处理相关的应用程序中 ...
- 吴裕雄--天生自然TensorFlow2教程:链式法则
import tensorflow as tf x = tf.constant(1.) w1 = tf.constant(2.) b1 = tf.constant(1.) w2 = tf.consta ...
- css属性书写顺序(重点)
- c++ 读取、输出txt文件
下面这段话转自:https://blog.csdn.net/lightlater/article/details/6326338 关于文本文件的文件头 第一 ANSI文件的文件头为空,不需要处理: 第 ...
- java 基础--8 种基本数据类型:整型、浮点型、布尔型、字符型 整型中 byte、short、int、long 的取值范围 什么是浮点型?什么是单精度和双精度?为什么不能用浮点型表示金额?
一.8种基本数据类型(4整,2浮,1符,1布): 整型:byte(最小的数据类型).short(短整型).int(整型).long(长整型): 浮点型:float(浮点型).double(双精度浮点 ...