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 ... 
随机推荐
- Octopus501工作站 安装记录
			cmake libreadline-dev 没有运行程序,nvidia-smi查看GPU-Util 达到100% 解决方案:需要把驱动模式设置为常驻内存才可以,设置命令:nvidia-smi -pm ... 
- [转][c++]关于构造函数不能有返回类型的错误
			转自:https://blog.csdn.net/sky_freebird/article/details/6687892 构造函数不能有返回类型,可是自己定义的构造函数本来就没写返回类型啊. 最后发 ... 
- svg轻松实现文字水印
			1. 水印图片生成采用svg,这样可以运行时生成名字或其他信息的图片 svg模板 <svg xmlns="http://www.w3.org/2000/svg" xmlns: ... 
- notepad++之个性化配置
			在Linux下,喜欢用vi做文件编辑(vim反倒没怎么用).在Windows系统下,用得最多的则是notepad++.开源大法好.. 之所以选择notepad++,是因为其不会强制你命名并保存文件,你 ... 
- Mac  AXURE9 汉化
			1.下载汉化文件 https://pan.baidu.com/s/1qE0ZSvf210WLMfvi8RlMpg 2.把lang文件放在Resources文件夹下 3.重新打开Axure就ok了 
- [K8s] Kubernetes 是什么 不是什么
			现在有三种部署方式,传统物理机部署.虚拟机部署.容器化部署. 我们现在所使用的云上服务器一般都是虚拟化出来的,硬件资源独立,操作系统等软件资源亦独立. 容器化的好处是更轻量,复用下层的操作系统,相当于 ... 
- spring boot实现切割分片上传
			文件上传是web开发中经常会遇到的 springboot的默认配置为10MB,大于10M的是传不上服务器的,需要修改默认配置 但是如果修改支持大文件又会增加服务器的负担. 当文件大于一定程度时,不仅服 ... 
- spring  boot 实现定时任务
			定时任务或者说定时调度,是系统中比较普遍的一个功能,例如数据归档.清理,数据定时同步(非实时),定时收发等等都需要用到定时任务,常见的定时调度框架有Quartz.TBSchedule等. 如何在Spr ... 
- Hadoop window win10 基础环境搭建(2.8.1)(转)
			下面运行步骤除了配置文件有部分改动,其他都是参照hadoop下载解压的share/doc/index.html. hadoop下载:http://apache.opencas.org/hadoop/c ... 
- 【转载,备忘】SQL Server 更改跟踪(Chang Tracking)监控表数据
			一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 主要区别与对比(Compare) 实现监控表数据步骤(Process) 参考文献(Refere ... 
