洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图
第一次做最小割,不是很理解。
https://www.luogu.org/problemnew/show/P1361
要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点,价值就是边的容量。
然后最小割一定会割断每个中间结点的两边的其中一边,这样最大价值就顺带求出来了。
在这道题里面额外还有某些点成组出现的额外价值。题解的办法是分别虚拟两个结点代表两个集合,源点到集合a的容量是其价值,然后从a连到他的附属结点各边容量为无穷。无穷的边不能被最小割割断。所以要么是把a的从属结点到t的边全部割断,然后多出来a的附加价值,要么是把s到a的附加价值边割断使a不能流向t。画个图发现很巧妙。
转载自:https://www.luogu.org/blog/ButterflyDew/solution-p1361
这个属于最大权闭合子图,意思是某个节点(集合)若被选中则它的从属结点都要被选中,这种情况就原图建无穷流量边,各正权点连S容量为权,负权点连T容量为权的绝对值。答案=所有正权点的和-最小割。
当最小割割断右边的负权点的边的时候意味着你付出相应的代价购买它留在左边,当最小割割断左边的时候意味着你舍弃了他的价值但是也不用付出割断他的代价。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e6+,M=2e6+;
int n,m,s,t,tot=,lnk[N],ter[M],nxt[M],val[M],dep[N],cnr[N]; void add(int u,int v,int w) {
ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot,val[tot]=w;
} void addedge(int u,int v,int w) {
add(u,v,w),add(v,u,);
} int bfs(int s,int t) {
memset(dep,,sizeof(dep));
memcpy(cnr,lnk,sizeof(lnk));
std::queue<int> q;
q.push(s),dep[s]=;
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=lnk[u];i;i=nxt[i]) {
int v=ter[i];
if(val[i]&&!dep[v]) q.push(v),dep[v]=dep[u]+;
}
}
return dep[t];
} int dfs(int u,int t,int flow) {
if(u==t) return flow;
int ans=;
for(int i=cnr[u];i&&ans<flow;i=nxt[i]) {
cnr[u]=i;
int v=ter[i];
if(val[i]&&dep[v]==dep[u]+) {
int x=dfs(v,t,std::min(val[i],flow-ans));
if(x) val[i]-=x,val[i^]+=x,ans+=x;
}
}
if(ans<flow) dep[u]=-;
return ans;
} ll dinic(int s,int t) {
ll ans=;
while(bfs(s,t)) {
ll x;
while((x=dfs(s,t,<<))) ans+=x;
}
return ans;
} int main() {
ll sum=; scanf("%d",&n);
s=,t=; for(int i=;i<=n;i++){
int u=s,v=i,w;
scanf("%d",&w);
addedge(u,v,w);
sum+=w;
} for(int i=;i<=n;i++){
int u=i,v=t,w;
scanf("%d",&w);
addedge(u,v,w);
sum+=w;
} int m;
scanf("%d",&m); int id=n+;
while(m--) {
int k;
scanf("%d",&k);
int w1,w2;
scanf("%d%d",&w1,&w2);
addedge(s,id,w1);
addedge(id+,t,w2); sum+=w1+w2; for(int i=;i<k;i++){
int x;
scanf("%d",&x);
addedge(id,x,0x3f3f3f3f);
addedge(x,id+,0x3f3f3f3f);
}
id+=;
}
printf("%lld\n",sum-dinic(s,t));
return ;
}
洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图的更多相关文章
- 【BZOJ-3438】小M的作物 最小割 + 最大权闭合图
3438: 小M的作物 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 825 Solved: 368[Submit][Status][Discuss ...
- 洛谷 P1361 小M的作物 解题报告
P1361 小M的作物 题目描述 小M在MC里开辟了两块巨大的耕地\(A\)和\(B\)(你可以认为容量是无穷),现在,小\(P\)有\(n\)中作物的种子,每种作物的种子有1个(就是可以种一棵作物) ...
- [BZOJ3438][洛谷P1361]小M的作物
题目大意:有A.B两个集合和n个物品,每个物品只能放在一个集合里.每个物品放在不同集合内能获得不同价值.有一些物品,如果它们同时放在一个集合内,则会产生新的价值(A和B中都有且不一定相同(c1和c2) ...
- 【POJ 2987】Firing (最小割-最大权闭合子图)
裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...
- [模拟赛FJOI Easy Round #2][T3 skill] (最小割+最大权闭合子图(文理分科模型))
[题目描述] 天上红绯在游戏中扮演敏剑,对于高攻击低防御的职业来说,爆发力显得非常重要,为此,她准备学习n个技能,每个技能都有2个学习方向:物理攻击和魔法攻击.对于第i个技能,如果选择物理攻击方向,会 ...
- [洛谷P1361]小M的作物
题目大意:将作物种在A,B两地,对于每种作物,种A,B分别有不同的收益,对于一些特殊的作物集合,共同种到A,B集合分别有一些额外收益.求最大收益. 题解:最小割,S向i连容量为$a_i$的边,i向T连 ...
- P1361 小M的作物 最小割理解
如果没有组合效益的存在 我们直接每个点两部分的最大值即可 换成网络流模型来看 即把S点看作是A田 把T点看作是B田 每种作物看作一个点 分别连边(S,i,A[i]) (i,T,B[i]) 最后图中所有 ...
- [P1361] 小M的作物 - 最小割
没想到今天早上的第一题网络流就血了这么多发 从经典的二选一问题上魔改 仍然考虑最小割 #include <bits/stdc++.h> using namespace std; #defi ...
- BZOJ.1497.[NOI2006]最大获利(最小割 最大权闭合子图Dinic)
题目链接 //裸最大权闭合子图... #include<cstdio> #include<cctype> #include<algorithm> #define g ...
随机推荐
- PHP拓展开发
痛定思痛: 开始了解 PHP 拓展开发,下面这篇文章不错!照着文章讲的,终于实现了! m.php的代码 浏览器访问 m.php 文件!(备注:在linux 命令行中 php -r 'cthulhu() ...
- SolidEdge如何复制特征 建立类似于UG 块的概念
直接Ctrl+C和Ctrl+V可以实现特征的复制粘贴 按N键可以改变特征方向 已经复制完成的特征要进行定位,则右击该特征,编辑轮廓,可以进行聪慧尺寸的标注 使用特征库的方式,就像UG的块一样, ...
- PHP开发的一些趣事
配置运行环境studyPhp: http://www.phpstudy.net/phpstudy/PhpStudy20180211.zip PHP运行环境:5.4 首先做的是一个表单测试吧 <! ...
- weex 项目开发(五)自定义 过滤函数 和 混合 及 自定义 Header 组件
1.自定义 过滤函数 src / filters / index.js /** * 自定义 过滤函数 */ export function host (url) { if (!url) return ...
- LeetCode_3Sum Closest
一.题目 3Sum Closest Total Accepted: 32191 Total Submissions: 119262My Submissions Given an array S of ...
- IO管理与磁盘调度
- TestNG – Dependency Test
转自:http://www.mkyong.com/unittest/testng-tutorial-7-dependency-test/ In TestNG, we use dependOnMetho ...
- 【php】读取"文件列表"按时间倒序显示,并递归显示各层文件夹、!
思路: 1.读取该php所在文件夹的文件列表,用"改动时间.文件名称"做键值对,塞入数组.对"改动时间"倒序.(貌似不能直接按时间倒序读取文件列表,此处为间接方 ...
- yum 安装 mysql
安装 yum -y install mysql-server 开机自启动 chkconfig mysqld on 设置账户密码 启动 service mysqld start -- 进入mysql库 ...
- 常用到的JS 验证(包括例子)
//验证是否为空 function check_blank(obj, obj_name){ if(obj.value != ''){ retur ...