洛谷 - P1361 小M的作物(最大流最小割)
题目链接:点击查看
题目大意:给出 n 个植物,每个植物种在 A 农场的收益是 a[ i ] ,种在 B 农场的收益是 b[ i ] ,再给出 m 组关系,每组中的所有植物如果都在 A 农场的话额外收益为 c1 ,如果同时在 B 农场的话额外收益为 c2,问如何种植可以使得收益最大
题目分析:每种植物的两种选择可以视为两个集合,对于选择农场 A 和农场 B 这个条件我们可以将每个点与源点和汇点连边,求一下最小割就能得到方案了,如果加上下面的那些组合的条件的话,需要我们建立虚点,大概如下图所示
其中 st 表示源点,ed 表示汇点,点 A 和点 B 表示两种植物,浅蓝色的表示第一个条件的建边
x1 和 x2 为我们建立的虚点,目的是为了限流,两条橙色的边分别是 c1 和 c2 ,这样不难发现,只有当与虚点相连的所有点都被分到同一个集合时,才可能会保留下来一条橙色的边,其他情况下两条橙色的边都是需要断开的
我们为了只断橙色的边而不影响深蓝色的边,可以选择将深蓝色的边赋值为无穷大
- 源点 -> 每个点,流量为 a[ i ]
- 源点 -> 虚点1,流量为 c1
- 虚点1 -> 相应的点,流量为 inf
- 相应的点 -> 虚点2,流量为 inf
- 虚点2 -> 汇点,流量为 c2
- 每个点 -> 汇点,流量为 b[ i ]
答案就是所有的 a[ i ] + b[ i ] + c1 + c2 之和减去最小割了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=3e3+100;struct Edge
{int to,w,next;
}edge[N*N];//边数int head[N],cnt;void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{memset(now,0,sizeof(now));memset(head,-1,sizeof(head));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);init();int n,st=N-1,ed=st-1,sum=0;scanf("%d",&n);for(int i=1;i<=n;i++){int val;scanf("%d",&val);addedge(st,i,val);sum+=val;}for(int i=1;i<=n;i++){int val;scanf("%d",&val);addedge(i,ed,val);sum+=val;}int m;scanf("%d",&m);for(int i=1;i<=m;i++){int k;scanf("%d",&k);int c1,c2;scanf("%d%d",&c1,&c2);sum+=c1+c2;addedge(st,n+i*2-1,c1);addedge(n+i*2,ed,c2);while(k--){int x;scanf("%d",&x);addedge(n+i*2-1,x,inf);addedge(x,n+i*2,inf);}}printf("%d\n",sum-solve(st,ed));return 0;
}
洛谷 - P1361 小M的作物(最大流最小割)相关推荐
- 洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图
第一次做最小割,不是很理解. https://www.luogu.org/problemnew/show/P1361 要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点 ...
- (最小割)洛谷P1361 小M的作物
洛谷P1361 小M的作物 思路: 这是一个两者取一的模型,将点集一分为二. 最小割在数值上等同于最大流.割去权值和最小的边,使图分成两部分,割下来的边权值和为最小割. 对于此题,先不考虑种在一起的情 ...
- 网络流建图方法(二)——辅助点(虚点)决策法洛谷 P1361 小M 的作物 Dinic
inic声明:本博客默认读者会最大流最小割的定理,会Dinic, 最小割在数值上 == 最大流 但是在意义上没有任何关系,姑且可以这样求得最小割,当然可以自行百度最小割的证明定理 还是从题目开始说起 ...
- P1361 小M的作物(最小割)
P1361 小M的作物(最小割) 比较板子的题,关键是建图. 答案就是 s u m − sum- sum−最小割. 而根据最小割最大流定理,即可求出最小割. 复习一下 Dinic 算法流程: bfs给 ...
- DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山
DFS(剪枝与优化) - 洛谷 P1361 - 小猫爬山 翰翰和达达饲养了N只小猫,这天,小猫们要去爬山. 经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了(呜咕>_&l ...
- 洛谷 P4430 小猴打架
洛谷 P4430 小猴打架 题目描述 一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友.每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友.经过N-1次打 ...
- 2017提高组D1T1 洛谷P3951 小凯的疑惑
洛谷P3951 小凯的疑惑 原题 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付的.现在小 凯想 ...
- 洛谷 P2186 小Z的栈函数
洛谷 P2186 小Z的栈函数 题目 题目描述 小Z最近发现了一个神奇的机器,这个机器的所有操作都是通过维护一个栈来完成的,它支持如下11个操作: NUM X:栈顶放入X. POP:抛弃栈顶元素. I ...
- 【01背包求方案数模板】洛谷 P1164 小A点菜
洛谷 P1164 小A点菜 https://www.luogu.org/problemnew/show/P1164 题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆, ...
最新文章
- windows hider
- 正确预测适合自己的职业
- python精通书籍-清华学霸整理,Python入门到精通这几本书帮你快速入行
- Linux分区如何表示,Linux中硬盘分区的表示方法
- SpringBoot整合Redis缓存中间件
- Kafka如何做到全局有序
- springboot redis mysql 自动同步_BAT一线互联网常考面试题:Spring+并发编程+JVM+设计模式+Redis...
- Mac连局域网打印机
- Fastadmin读取数据库配置
- iP地址查询、手机号归属地查询
- Transform.up与Vector3.up
- 史上最全面Java面试汇总(面试题+答案)
- 华为手机8.0.0怎么找到云相册_华为手机里的相册照片删除了怎么找回?
- 例7.14 有一个一维数组,内放10个学生成绩,写一个函数,当主函数调用此函数后,能求出平均分、最高分和最低分。
- 抖音算法推荐机制详解
- 获取已安装或未安装的apk签名
- 打破边界,边缘计算有何应用场景?
- 3G时代的移动业务赢利模式分析
- 加州伯克利计算机科学录取,【哈鲁2019录取】恭喜哈鲁学员喜提加州伯克利大学计算机科学专业录取!...
- Servlet之 http://localhost:8080/ 详解