3438: 小M的作物

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1891  Solved: 801
[Submit][Status][Discuss]

Description

小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子
有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可以获得ai的收益,在B中种植
可以获得bi的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益
,小M找到了规则中共有m种作物组合,第i个组合中的作物共同种在A中可以获得c1i的额外收益,共同总在B中可以
获得c2i的额外收益,所以,小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么?

Input

第一行包括一个整数n
第二行包括n个整数,表示ai第三行包括n个整数,表示bi第四行包括一个整数m接下来m行,
对于接下来的第i行:第一个整数ki,表示第i个作物组合中共有ki种作物,
接下来两个整数c1i,c2i,接下来ki个整数,表示该组合中的作物编号。输出格式

Output

只有一行,包括一个整数,表示最大收益

Sample Input

3
4 2 1
2 3 2
1
2 3 2 1 2

Sample Output

11
样例解释A耕地种1,2,B耕地种3,收益4+2+3+2=11。
1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过2*10^9。

题解

被洛谷大佬刷到绿了 好过分QAQ

读了题之后就在想怎么处理组合和个体之间的不相容性。一开始打算用拆点的方法限流,然后粗略算了一下 边数会爆炸QAQ

然后看了题解(=_=),fa现可以巧妙的用上最小割

把源点当作A,汇点当作B,源点往每个作物连ai,作物往B连bi。

首先对于没有组合:

割一下,留在左边的种进A,右边的种进B,那么收益就是剩下来的边权之和。

对于组合:

建一个虚点,从源点连一条c1i,再往每个受它控制的点连INF;

再建一个虚点,往汇点连一条c2i,再从每个受它控制的点连INF;

(图是毛来的)

其中黄边为对应值,蓝边为INF

以下为建图合理性的证明:

首先,INF永远割不掉。

对于左边,如果S->c已经被割掉,也就是说c变成了B的大宝贝儿,

想让c这条支流断掉,有两种选择:割左边的黄线,或者把右边的黄线和c->T一起割掉。

而如果割右边的,则不符合一开始让c加入B战队的假定,且S->c割的不明不白。

所以反证得知此时左边的黄线肯定会断。

同理可证,如果c->T被割掉,X'到T也会断。

∴证得割掉组合内任意点,这个组合的群体优惠也会断掉。

而如果某个组合的左边黄线存在,

那么割它下面的绿线都是白割,反正过的去。

对于右边同理。

∴如果某个组合优惠被得到了,那么它的所有儿砸都会留下。易知此时流量既得到了组合优惠,也收到了单个收益。

所以这样建图是ojbk的。

建了图然后跑个dinic算最小割,再用总边权减一下就好了。

撒花~

#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF=*1e9+;
struct emm{
int e,f,v;
}a[];
int h[];
int tot=;
int s,t;
void con(int x,int y,int w)
{
a[++tot].f=h[x];
h[x]=tot;
a[tot].e=y;
a[tot].v=w;
a[++tot].f=h[y];
h[y]=tot;
a[tot].e=x;
return;
}
queue<int>q;
int d[];
inline bool bfs()
{
memset(d,,sizeof(d));
d[s]=;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=h[x];i;i=a[i].f)
if(!d[a[i].e]&&a[i].v)
{
d[a[i].e]=d[x]+;
q.push(a[i].e);
}
}
return d[t];
}
int dfs(int x,int al)
{
if(x==t||!al)return al;
int fl=;
for(int i=h[x];i;i=a[i].f)
if(d[a[i].e]==d[x]+&&a[i].v)
{
int f=dfs(a[i].e,min(a[i].v,al));
if(f)
{
fl+=f;
al-=f;
a[i].v-=f;
a[i^].v+=f;
if(!al)break;
}
}
if(!fl)d[x]=-;
return fl;
}
int main()
{
//freopen("a.in","r",stdin);
int n;
scanf("%d",&n);
s=,t=;
long long all=;
for(int i=;i<=n;++i)
{
int x;
scanf("%d",&x);
all+=x;
con(s,i,x);
}
for(int i=;i<=n;++i)
{
int x;
scanf("%d",&x);
all+=x;
con(i,t,x);
}
int m;
scanf("%d",&m);
int nod=n;
for(int i=;i<=m;++i)
{
int ki,c1,c2;
scanf("%d%d%d",&ki,&c1,&c2);
nod++;
con(s,nod,c1);
con(nod+,t,c2);
all+=c1;
all+=c2;
for(int j=;j<=ki;++j)
{
int x;
scanf("%d",&x);
con(nod,x,INF);
con(x,nod+,INF);
}
nod++;
}
long long ans=;
while(bfs()){ans+=dfs(s,INF);}
cout<<all-ans;
return ;
}

「BZOJ3438」小M的作物(最小割的更多相关文章

  1. 【BZOJ3438】小M的作物 最小割

    [BZOJ3438]小M的作物 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1. ...

  2. 【BZOJ-3438】小M的作物 最小割 + 最大权闭合图

    3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 825  Solved: 368[Submit][Status][Discuss ...

  3. BZOJ3438小M的作物——最小割

    题目描述 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1...n编号),现在,第i种作物种植在A中种植可 ...

  4. BZOJ 3438: 小M的作物( 最小割 )

    orz出题人云神... 放上官方题解... 转成最小割然后建图跑最大流就行了... ---------------------------------------------------------- ...

  5. 「SHOI2007」「Codevs2341」 善意的投票(最小割

    2341 善意的投票 2007年省队选拔赛上海市队选拔赛 时间限制: 5 s 空间限制: 128000 KB 题目等级 : 大师 Master   题目描述 Description 幼儿园里有n个小朋 ...

  6. 3438: 小M的作物[最小割]

    3438: 小M的作物 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1073  Solved: 465[Submit][Status][Discus ...

  7. P1361 小M的作物 最小割理解

    如果没有组合效益的存在 我们直接每个点两部分的最大值即可 换成网络流模型来看 即把S点看作是A田 把T点看作是B田 每种作物看作一个点 分别连边(S,i,A[i]) (i,T,B[i]) 最后图中所有 ...

  8. 洛谷 - P1361 - 小M的作物 - 最小割 - 最大权闭合子图

    第一次做最小割,不是很理解. https://www.luogu.org/problemnew/show/P1361 要把东西分进两类里,好像可以应用最小割的模板,其中一类A作为源点,另一类B作为汇点 ...

  9. [P1361] 小M的作物 - 最小割

    没想到今天早上的第一题网络流就血了这么多发 从经典的二选一问题上魔改 仍然考虑最小割 #include <bits/stdc++.h> using namespace std; #defi ...

随机推荐

  1. LeetCode OJ--Implement strStr()

    http://oj.leetcode.com/problems/implement-strstr/ 判断一个串是否为另一个串的子串 比较简单的方法,复杂度为O(m*n),另外还可以用KMP时间复杂度为 ...

  2. eclispe集成web插件

    最近公司需要使用开源框架开发,所有下载了最新版本的eclispe工具,但是在官网下载的eclispe是不包含web插件的,无法创建web项目,需要自行集成web插件 eclipse官网下载地址:htt ...

  3. db2 获取自增主键的方法

    1.用SEQUENCES方式 建表语句 CREATE TABLE TEST1( PKEY INTEGER NOT NULL, NAME VARCHAR(100), SEX VARCHAR(100), ...

  4. 洛谷 P1034 矩形覆盖

    P1034 矩形覆盖 题目描述 在平面上有nn个点(n \le 50n≤50),每个点用一对整数坐标表示.例如:当 n=4n=4 时,44个点的坐标分另为:p_1p1​(1,11,1),p_2p2​( ...

  5. xgboost调参

    The overall parameters have been divided into 3 categories by XGBoost authors: General Parameters: G ...

  6. c++中c_str()函数

    https://zhidao.baidu.com/question/104592558.html

  7. BUPT复试专题—List(2015)

    题目描述 在该LIST上实现3种操作 1.append x在该LIST末尾添加x,x是32位整数 2.pop删除该LIST末尾的数 3.find i寻找第i个数,若i为负数表示寻找倒数第i个数,例如i ...

  8. Android安全机制介绍

    Android的安全机制包含下面几个方面:      • 进程沙箱隔离机制.      • 应用程序签名机制.      • 权限声明机制.      • 訪问控制机制.      • 进程通信机制. ...

  9. Oracle RAC cache fusion原理測试

    Oracle RAC cache fusion是RAC最核心的工作机制.他把全部实例的SGA虚拟成一个大的SGA区,每当不同的实例请求同样的数据块,这个数据块就须要在实例间进行传递. 那究竟什么时候传 ...

  10. LeetCode(26)题解:Remove Duplicates from Sorted Array

    https://leetcode.com/problems/remove-duplicates-from-sorted-array/ Given a sorted array, remove the ...