\(\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 题」太空飞行计划的更多相关文章

  1. LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

    #6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测 ...

  2. Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)

    Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...

  3. 【刷题】LOJ 6001 「网络流 24 题」太空飞行计划

    题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 \(E = \{ E_1, E_2, \cdots, E_m ...

  4. LOJ6001 - 「网络流 24 题」太空飞行计划

    原题链接 Description 有个实验和个仪器,做实验有报酬买仪器有花费.每个实验都需要一些仪器,求最大净收益(实验报酬仪器花费),并输出一组方案. Solution 实验向所需仪器连边,实验的点 ...

  5. LibreOJ #6000. 「网络流 24 题」搭配飞行员

    二次联通门 : LibreOJ #6000. 「网络流 24 题」搭配飞行员 /* LibreOJ #6000. 「网络流 24 题」搭配飞行员 二分图最大匹配 Dinic最大流 + 当前弧优化 */ ...

  6. LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集

    #6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   ...

  7. LibreOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

    #6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  8. LIbreOJ #6011. 「网络流 24 题」运输问题 最小费用最大流

    #6011. 「网络流 24 题」运输问题 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  9. LibreOJ #6008. 「网络流 24 题」餐巾计划 最小费用最大流 建图

    #6008. 「网络流 24 题」餐巾计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

随机推荐

  1. 解决Zookeeper无法启动的问题

    在启动zookeeper集群的单个zookeeper节点时总是报如下错误 [root@zookeeper1 zookeeper-3.4.5]# bin/zkServer.sh status JMX e ...

  2. 06-Docker-Image管理操作

    目录 06-Docker-Image管理操作 参考 镜像命名规范 镜像管理命令 1. 拉取推送 2. 查看操作 3. 本地删除 4. 创建标签 5. 导出导入 06-Docker-Image管理操作 ...

  3. dapper基本操作

    https://www.cnblogs.com/vichin/p/9289969.html

  4. WebApplicationInitializer初始化web应用,不需要web.xml

    web应用的上下文层次结构 很多时候加的切面不起作用,是因为加错地方了 1.直接初始化,上下文只有一个context import org.springframework.web.WebApplica ...

  5. Spring Boot RestApi 测试教程 Mock 的使用

    测试 Spring Boot Web 的时候,我们需要用到 MockMvc,即系统伪造一个 mvc 环境.本章主要编写一个基于 RESTful API 正删改查操作的测试用例.本章最终测试用例运行结果 ...

  6. 引入C/C++动态库

    [DllImport("SocketAPI.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = t ...

  7. 28 JavaScript语言类型&运算符

    语言类型: 弱类型:可以改变变量值和对象类型 强类型:可以改变变量值不能改变对象类型 解释型:边编译边执行,速度慢.解释型一般是弱类型 编译型:先编译再执行(C++\Java),速度快.编译型一般是强 ...

  8. springboot例子

    @Mapperpublic interface FinancingMapper { @Insert("<script>" + "insert into fin ...

  9. OBS输出设置

    参数建议来自虎牙 https://help.huya.com/284 3.输出: 1)编码器中x264相当于虎牙直播中的CPU H.264编码,NVENC H.264相当于虎牙直播中的NVIDIA H ...

  10. 《Interest Rate Risk Modeling》阅读笔记——第八章:基于 LIBOR 模型用互换和利率期权进行对冲

    目录 第八章:基于 LIBOR 模型用互换和利率期权进行对冲 思维导图 推导浮息债在重置日(reset date)的价格 第八章:基于 LIBOR 模型用互换和利率期权进行对冲 思维导图 推导浮息债在 ...