网络流建图方法(二)——辅助点(虚点)决策法洛谷 P1361 小M 的作物 Dinic
inic声明:本博客默认读者会最大流最小割的定理,会Dinic,
最小割在数值上 == 最大流
但是在意义上没有任何关系,姑且可以这样求得最小割,当然可以自行百度最小割的证明定理
还是从题目开始说起
洛谷P1361
题目描述
小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子有1个(就是可以种一棵作物)(用1…n编号)。
现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中可以获得c1i的额外收益,共同总在B中可以获得c2i的额外收益。
小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么?
输入格式
第一行包括一个整数n
第二行包括n个整数,表示ai第三行包括n个整数,表示bi第四行包括一个整数m接下来m行,
对于接下来的第i行:第一个整数ki,表示第i个作物组合中共有ki种作物,
接下来两个整数c1i,c2i,接下来ki个整数,表示该组合中的作物编号。
输出格式
只有一行,包括一个整数,表示最大收益
输入输出样例
**输入 **
3
4 2 1
2 3 2
1
2 3 2 1 2
**输出 **
11
如果说我们不考虑额外的收益那么我们很容易建立如下的模型
这样建图后我们在跑一遍最大流求得最小割就好了,有些人不清楚为什么要求最小割这里简单的解释一下,我们建立原点和汇点分别表示两块地但是如果即链接了A又连接了B那肯定是不行的,因为一种作物只可以种植在唯一的土地上,那么也就是说我们必须要断开一条边,既然要取得最大的收益那么我们肯定要断掉最小的边,咦~~~~~~~~~这不是最小割嘛233333;
但是现在有一种额外收益的情况,那我们就要建立关于额外收益的点,也就是辅助点或者说是虚点
那么我们建立如下模型
我们建立两个虚点,v1和v2分别表示一个集合对A或者B作出贡献的收益点,这样我们跑一遍最大流求出最小割,就OKK了 啊
AC代码
/** ┏┓ ┏┓+ +* ┏┛┻━━━━━━━┛┻┓ + +* ┃ ┃* ┃ ━ ┃ ++ + + +* █████━█████ ┃+* ┃ ┃ +* ┃ ┻ ┃* ┃ ┃ + +* ┗━━┓ ┏━┛* ┃ ┃* ┃ ┃ + + + +* ┃ ┃ Code is far away from bug with the animal protecting* ┃ ┃ + 神兽保佑,代码无bug* ┃ ┃* ┃ ┃ +* ┃ ┗━━━┓ + +* ┃ ┣┓* ┃ ┏┛* ┗┓┓┏━━━┳┓┏┛ + + + +* ┃┫┫ ┃┫┫* ┗┻┛ ┗┻┛+ + + +*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<string>
#include<vector>
#include<cmath>
#include<functional>
#include<stack>using namespace std;const int maxn = 255;
const int MAXN = 4e6 + 5;
const int INF = 0x3f3f3f3f;struct Edge
{int to, w, next;
}edg[MAXN];int head[MAXN], dep[MAXN], cnt = 0;void init()
{memset(head, -1, sizeof(head));cnt = 0;
}void Add_edge(int u, int v, int w)
{edg[cnt].w = w;edg[cnt].to = v;edg[cnt].next = head[u];head[u] = cnt++;edg[cnt].w = 0;edg[cnt].to = u;edg[cnt].next = head[v];head[v] = cnt++;
}bool Bfs(int s, int t)
{memset(dep, 0, sizeof(dep));queue<int> q;while(!q.empty()) q.pop();dep[s] = 1;q.push(s);while(!q.empty()){int p = q.front();q.pop();for(int i = head[p]; i != -1; i = edg[i].next){int w = edg[i].w; int v = edg[i].to;if(w && !dep[v]){dep[v] = dep[p] + 1;q.push(v);if(v == t)return true;}}}if(dep[t])return true;elsereturn false;
}int DFS(int s, int mw, int t)
{if(s == t)return mw;int res = mw;for(int i = head[s]; i != -1; i = edg[i].next){if(!res) return mw;int v = edg[i].to;if(edg[i].w && dep[v] == dep[s] + 1){int k = DFS(v, min(res, edg[i].w), t);if(!k) dep[v] = 0;edg[i].w -= k;edg[i^1].w += k;res -= k;}}return mw - res;
}int Dinic(int s, int t)
{int tot = 0;while(Bfs(s, t)){while(int d = DFS(s, INF, t))tot += d;}return tot;
}//最小割在数值上等于最大流
//辅助点建图法int main()
{int n, w, m, k, c1, c2, u;long long sum = 0;scanf("%d", &n);init();int s = n + 1, t = n + 2;register int i;for(i = 1; i <= n; ++i){scanf("%d", &w);sum += w;Add_edge(s, i, w);}for(i = 1; i <= n; ++i){scanf("%d", &w);sum += w;Add_edge(i, t, w);}scanf("%d", &m);for(int a = 1; a <= m; ++a){scanf("%d %d %d", &k, &c1, &c2);int v1 = n + 2 + a;int v2 = n + 2 + a + m;sum += (c1 + c2);Add_edge(s, v1, c1);Add_edge(v2, t, c2);for(int j = 1; j <= k; ++j){scanf("%d", &u);Add_edge(v1, u, INF);Add_edge(u, v2, INF);}}cout << sum - Dinic(s, t);
}
有一个 坑点就是数据范围要开到4e6才能过,,,,切记初始化
网络流建图方法(二)——辅助点(虚点)决策法洛谷 P1361 小M 的作物 Dinic相关推荐
- 二分图常用建图方法及其性质
建图方法 https://wenku.baidu.com/view/63c1a01655270722192ef7c3.html 性质 http://dsqiu.iteye.com/blog/16895 ...
- orb特征 稠密特征_一种基于ORB-SLAM2的双目三维稠密建图方法技术
本发明专利技术公开了一种基于ORB‑SLAM2的双目稠密建图方法,涉及机器人同步定位与地图创建领域,该方法主要由跟踪线程.局部地图线程.闭环检测线程和稠密建图线程组成.其中稠密建图线程包含以下步骤:1 ...
- LIOM: 一种新的激光惯性里程计和建图方法
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者:robot L | 来源:知乎 https://zhuanlan.zhihu.com/p/137 ...
- 二分图最大匹配及常用建图方法
算法---艺术 二分图匹配剖析 很多人说,算法是一种艺术.但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力. 这让我追求算法的脚步不能停止.下面我通过分析匈牙利算法以及常用 ...
- 视觉slam中的一种单目稠密建图方法
之所以只讲单目的稠密建图,这是因为,首先,对于RGBD图,我们已知所有点的深度,可以直接生成稠密的点云.其次,对于稀疏地图,其实很多VO中已经完成了稀疏地图的构建,但是稀疏地图只能用于定位,不能用于导 ...
- EAI激光雷达X4使用gmapping与laser_scan_matcher建图(二)
以下便是gmapping+laser_scan_matcher提供的2Dpose的launch文件源码,这里将laser_scan_matcher提供的2Dpose当作里程计来使用: <!-- ...
- HDU 3338 网络流 建图
原题位置http://acm.hdu.edu.cn/showproblem.php?pid=3338 这道题的意思就是 给你一个由黑白方格构成的图 白方格全部空着 黑方格有的会有数字 在左下角的数字表 ...
- 【UOJ575】光伏元件【网络流建图】【上下界网络流】【费用流】
题意: n×nn\times nn×n 的 01 矩阵,对于 i∈[1,n]i \in [1,n]i∈[1,n] 有三个参数 li,li,kil_i,l_i,k_ili,li,ki,表示第 ii ...
- HDU4411 Arrest(负边权或上下界网络流建图)
牵涉到必须经过每个点至少一次,所以拆点 把点iii拆分为iii和i+ni+ni+n iii到i+ni+ni+n可以走多次,但至少需要经过一次(代表经过这个点) 所以iii到i+ni+ni+n首先连一条 ...
最新文章
- HttpApplication事件ASP.NET页面周期
- centos mysql压缩文件直接恢复_Centos下mysql数据库备份与恢复的方法
- arm汇编:.balignl伪指令理解
- 【测绘程序设计】高斯克吕格投影:带号及中央经度计算神器V1.0(附源程序)
- 【 Grey Hack 】万金油脚本:常见端口漏洞检测
- [js] 请使用js实现一个秒表计时器的程序
- Debugging with GDB (2) 调用GDB
- 函数的定义、返回值和参数
- 资料分析-增长率 比重 平均数 倍数等
- 如何打出日语中的叠字符号「々」
- css3缓慢出现,让CSS3旋转开始缓慢然后结束缓慢?
- 【数智化人物展】网智天元莫倩:“感、联、知、控”,四步方可打造企业数智化转型升级路径...
- 电脑键盘equals在哪个位置_电脑键盘符号
- 线性代数中满足乘法交换律的运算-行列式与迹
- 大数据实战项目 -- 离线数仓
- node 连接MySQL
- Linux系统调用之lseek函数
- linux 存储映射lun 给_LINUX系统下添加映射存储LUN
- 我想唱歌给你听~~~
- 苹果AI秀——Core ML强势来袭