P1361 小M的作物 (最大流)
题目
解析
把\(A\)看做源点,把\(B\)看做汇点,先不考虑额外情况

显然,这是一种两者选其一的问题,我们选择一部分边割去,使这部分边的贡献最小,就是求最小割,我们求出了收益最小的情况,又因为只有两种情况,我们取了每一种情况收益较小的一种,所以我们要求的就是总流量-最小割。
然后考虑额外收益的情况,对于每一个额外收益,要么对\(A\)产生影响,要么对\(B\)产生影响,要么两者都不产生影响,所以显然不能直接增加已有的边中的流量,否则会出现同时加\(AB\)的额外贡献的情况,所以建立一个新点,从A向新点连一条边,边权为额外的收益,

然后从新点向其组合分别连\(INF\)的边,因为如果\(1,2\)被分到了\(B\)田的话,\(s->1,s->2\)的所有路径上都至少要有一条边要断开,我们想要断开\(s->4\),也就是额外收益的边,怎么办,那就从\(4\)向\(1,2\)连流量为\(INF\)的边,流量为\(INF\)的边不会被切断,注意这里的\(INF\)应为\(0x7fffffff\)。
所以对于\(A\)田这样建图

\(B\)田同理

代码
#include <bits/stdc++.h>
using namespace std;
const int N = 3e6 + 10;
const int INF = 0x7fffffff;
int n, m, num = 1, s, t, sum;
int head[N], cur[N], dep[N];
class node {
public :
int v, nx, w;
} e[N];
template<class T>inline void read(T &x) {
x = 0; int f = 0; char ch = getchar();
while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
x = f ? -x : x;
return;
}
inline void add(int u, int v, int w) {
e[++num].nx = head[u], e[num].v = v, e[num].w = w, head[u] = num;
e[++num].nx = head[v], e[num].v = u, e[num].w = 0, head[v] = num;
}
queue<int>q;
bool bfs() {
memset(dep, 0, sizeof dep);
memcpy(cur, head, sizeof cur);
dep[s] = 1;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = head[u]; ~i; i = e[i].nx) {
int v = e[i].v;
if (!dep[v] && e[i].w) dep[v] = dep[u] + 1, q.push(v);
}
}
return dep[t];
}
int dfs(int u, int flow) {
if (u == t) return flow;
int use = 0;
for (int &i = cur[u]; ~i; i = e[i].nx) {
int v = e[i].v;
if (e[i].w && dep[v] == dep[u] + 1) {
int di = dfs(v, min(e[i].w, flow));
e[i].w -= di, e[i ^ 1].w += di;
use += di, flow -= di;
if (flow <= 0) break;
}
}
return use;
}
int dinic() {
int ans = 0;
while (bfs()) ans += dfs(s, INF);
return ans;
}
int main() {
memset(head, -1, sizeof head);
read(n);
s = 5000, t = s + 1;
for (int i = 1, x; i <= n; ++i) read(x), add(s, i, x), sum += x;
for (int i = 1, x; i <= n; ++i) read(x), add(i, t, x), sum += x;
read(m);
for (int i = 1, k, a, b; i <= m; ++i) {
read(k);
read(a), read(b);
sum += (a + b);
add(s, n + i, a), add(n + m + i, t, b);
for (int j = 1, opt; j <= k; ++j) {
read(opt);
add(n + i, opt, INF), add(opt, n + m + i, INF);
}
}
printf("%d\n", sum - dinic());
}
P1361 小M的作物 (最大流)的更多相关文章
- P1361 小M的作物
P1361 小M的作物 题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号). 现在,第 ...
- 洛谷 P1361 小M的作物 解题报告
P1361 小M的作物 题目描述 小M在MC里开辟了两块巨大的耕地\(A\)和\(B\)(你可以认为容量是无穷),现在,小\(P\)有\(n\)中作物的种子,每种作物的种子有1个(就是可以种一棵作物) ...
- luogu P1361 小M的作物
题目链接 luogu P1361 小M的作物 题解 源汇点为A,B 向种子连边,容量为价值,每个种子能与A或B联通,考虑最小割 用建边的总流量减去最小割就是答案 相同利益的时候新建节点,由额外利益构成 ...
- P1361 小M的作物 【网络流】【最小割】
题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1...n编号). 现在,第i种作物种植在A中种植可 ...
- P1361 小M的作物 最小割理解
如果没有组合效益的存在 我们直接每个点两部分的最大值即可 换成网络流模型来看 即把S点看作是A田 把T点看作是B田 每种作物看作一个点 分别连边(S,i,A[i]) (i,T,B[i]) 最后图中所有 ...
- [洛谷P1361]小M的作物
题目大意:将作物种在A,B两地,对于每种作物,种A,B分别有不同的收益,对于一些特殊的作物集合,共同种到A,B集合分别有一些额外收益.求最大收益. 题解:最小割,S向i连容量为$a_i$的边,i向T连 ...
- 洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图
第一次做最小割,不是很理解. https://www.luogu.org/problemnew/show/P1361 要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点 ...
- [BZOJ3438][洛谷P1361]小M的作物
题目大意:有A.B两个集合和n个物品,每个物品只能放在一个集合里.每个物品放在不同集合内能获得不同价值.有一些物品,如果它们同时放在一个集合内,则会产生新的价值(A和B中都有且不一定相同(c1和c2) ...
- [P1361] 小M的作物 - 最小割
没想到今天早上的第一题网络流就血了这么多发 从经典的二选一问题上魔改 仍然考虑最小割 #include <bits/stdc++.h> using namespace std; #defi ...
随机推荐
- Research Guide: Pruning Techniques for Neural Networks
Research Guide: Pruning Techniques for Neural Networks 2019-11-15 20:16:54 Original: https://heartbe ...
- RSA后台签名前台验签的应用(前台采用jsrsasign库)
写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...
- Vscode 修改主题颜色
首先向大家演示如何使用VSCode自带的颜色主题:依次点击左上角的文件-首选项-颜色主题,出现如下的主题选取界面.
- Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题
转: Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题 在实际PL/SQL编程中,我们要对动态取出来的一组数据,进行For循环处理,其基本程序逻辑为: ...
- Docker入门-docker运行springboot应用(二)
环境准备 jdk8 安装docker 镜像加速器配置 docker私有仓库 springboot工程的jar包 docker部署项目 dockfile Dockfile是一种被Docker程序解释的脚 ...
- siglongjmp和sigsetjmp 用法
1. 引入原因 由于在信号处理期间自动屏蔽了正在被处理的信号,而使用setjmp/longjmp跳出信号处理程序时又不会自动将 信号屏蔽码修改会原来的屏蔽码,从而引起该信号被永久屏蔽. 可以使用sig ...
- traefik安装
注意这篇文档有个错误,需要改正一下: 1.nginx1-7.yaml nginx1-8.yaml traefik.yaml 这三个文件里面的80端口需要改成8080端口,否则报错,其他的文件不变. 2 ...
- replace into 详解 update mysql
转replace 与 update 区分本文主要对比一下 Sqlite 中的 replace 语句和 update 语句 . 在本例中使用如下数据库表: 图1 该表的表名为student, 存储学 ...
- Kafka Connect简介
Kafka Connect简介 http://colobu.com/2016/02/24/kafka-connect/#more Kafka 0.9+增加了一个新的特性Kafka Connect,可以 ...
- django数据库配置,即数据库分库分表
一 Django的数据库配置 (一)修改settings.py文件关于数据库的配置: Django默认使用sqlite: DATABASES = { 'default': { 'ENGINE': ...