【题解】小M的作物
\(\text{Solution:}\)
这题要求最大收获,可以转化为所有可能的收益减去最小割。
单个点很好连边 \((S\to pos\to T),\) 问题在于如何处理组合的点。
观察到,一个组合要不然全部都划分到某一个集合,要不然不做贡献。注意到组合里面的点是不能拆开的。
所以我们建立一个组合虚点,它连接所有组合内的点,边权是 \(\infty.\) 这样就一定可以避免把它们划分到不同集合中。
那么,我们可以考虑如下建模模型:
\(\text{S}\to \text{compose} \to \text{everypoints in this group} \to \text{compose endpoint} \to \text{T}.\)
本题我们可以把 \(A\) 看作 \(S,T\) 同理。
于是这个题再套上我们最熟悉的\(\text{Dinic}\)模板就过了。
最后来分析一下这个图的规模:
首先,所有点都应该有一个对应点,再加上每一个集合的开始点和结束点,共\(n+m+m\)个。最大是\(3000.\)
对于边:每个点对源点和汇点都会连边,这里是\(n+n.\)每一个组合,其边数是组合中的点数的两倍,共约为\(n+n+2mk.\)最大数据是\(2*10^6+2000.\)
根据\(Dinic\)的复杂度\(O(n^2 m)\)这个数量级显然会炸,但是出题人毕竟一定会让\(Dinic\)过,以及\(Dinic\)复杂度跑不满的原因,这个算法是可以过的。
#include<bits/stdc++.h>
using namespace std;
const int inf=(1<<30);
const int MAXN=2e6+10;
int tot=1,head[MAXN];
int dep[MAXN],cur[MAXN];
int n,a[MAXN],b[MAXN],m;
int Ans,c1[MAXN],c2[MAXN],S,T;
vector<int>v[MAXN];
struct E{int nxt,to,flow;}e[MAXN];
inline void add(int x,int y,int w){
e[++tot].to=y;e[tot].nxt=head[x];
e[tot].flow=w;head[x]=tot;
e[++tot].to=x;e[tot].nxt=head[y];
e[tot].flow=0;head[y]=tot;
}
bool bfs(int s,int t){
memset(dep,0,sizeof dep);
cur[s]=head[s];dep[s]=1;
queue<int>q;q.push(s);
while(!q.empty()){
s=q.front();
q.pop();
for(int i=head[s];i;i=e[i].nxt){
int j=e[i].to;
if(!dep[j]&&e[i].flow){
cur[j]=head[j];
dep[j]=dep[s]+1;
if(j==t)return true;
q.push(j);
}
}
}
return false;
}
int dfs(int s,int flow,int t){
if(flow<=0||s==t)return flow;
int rest=flow;
for(int i=cur[s];i;i=e[i].nxt){
int j=e[i].to;
if(dep[j]==dep[s]+1&&e[i].flow){
int tmp=dfs(j,min(rest,e[i].flow),t);
if(tmp<=0)dep[j]=0;
rest-=tmp;e[i].flow-=tmp;e[i^1].flow+=tmp;
if(rest<=0)break;
}
}
return flow-rest;
}
int dinic(int s,int t){
int ans=0;
for(;bfs(s,t);)ans+=dfs(s,inf,t);
return ans;
}
void Deal(){
S=0,T=n+m+m+1;
for(int i=1;i<=n;++i)add(S,i,a[i]),add(i,T,b[i]);
for(int i=1;i<=m;++i){
int pos=i+n;add(S,pos,c1[i]);
int posend=i+n+m;
for(int j=0;j<(int)v[i].size();++j)
add(pos,v[i][j],inf),add(v[i][j],posend,inf);
add(posend,T,c2[i]);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",a+i),Ans+=a[i];
for(int i=1;i<=n;++i)scanf("%d",b+i),Ans+=b[i];
scanf("%d",&m);
for(int i=1,k;i<=m;++i){
scanf("%d",&k);
scanf("%d%d",&c1[i],&c2[i]);
Ans+=c1[i];Ans+=c2[i];
for(int j=1,x;j<=k;++j){
scanf("%d",&x);
v[i].push_back(x);
}
}
Deal();
printf("%d\n",Ans-dinic(S,T));
return 0;
}
【题解】小M的作物的更多相关文章
- 善意的投票&小M的作物 题解
善意的投票: 因为只有\(2\)种意愿,不妨让想睡午觉的和源点连边,让不想睡午觉的和汇点连边.对于每一对好朋友,在他们之间连边.那么只要源点和汇点还联通,就存在一对好友是冲突的,我们现在要做的就是删去 ...
- BZOJ 3438: 小M的作物( 最小割 )
orz出题人云神... 放上官方题解... 转成最小割然后建图跑最大流就行了... ---------------------------------------------------------- ...
- BZOJ 3438 小M的作物 & BZOJ 1877 [SDOI2009]晨跑
我由衷地为我的朋友高兴.哈哈,yian,当你nick name破百上千时,再打“蒟蒻”就会被打的. 好的,说正事吧.请注意,这还是题解.但我发现,网络流实在是太套路了(怪不得这两年几乎销声匿迹).我们 ...
- 【BZOJ3438】小M的作物 最小割
[BZOJ3438]小M的作物 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1. ...
- luogu P1361 小M的作物
题目链接 luogu P1361 小M的作物 题解 源汇点为A,B 向种子连边,容量为价值,每个种子能与A或B联通,考虑最小割 用建边的总流量减去最小割就是答案 相同利益的时候新建节点,由额外利益构成 ...
- 「BZOJ3438」小M的作物(最小割
3438: 小M的作物 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1891 Solved: 801[Submit][Status][Discus ...
- bzoj3438: 小M的作物(那年花开最小割)
3438: 小M的作物 题目:传送门 题解: 最小割标准水题(做了几天的最小割之后表示是真的水) 为什么水:博主已经做过两道基本一样的题目了... 详情参考:bzoj3894 代码: #include ...
- 【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个(就是可以种一棵作物)(用1...n编号). 现在,第 ...
- BZOJ_3438_小M的作物_最小割
BZOJ_3438_小M的作物_最小割 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物) ...
随机推荐
- WebStorm下ReactNative代码提示设置
ReactNative 代码智能提醒 (Webstrom live template) https://github.com/virtoolswebplayer/ReactNative-LiveTe ...
- OC基础--字符串
前言 做iOS开发有3年了,从当初的小白到现在,断断续续看过很多资料,之前也写过一些博文来记录,但是感觉知识点都比较凌乱.所以最近准备抽时间把iOS开发的相关知识进行一个梳理,主要分为OC基础.UI控 ...
- 条件竞争(race condition)
条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生. 参考了一些资料,发现一个比较能说明问 ...
- Mybatis联合查询(一)
Mybatis的简单联合查询操作: 实体类: Employee: package com.test.mybatis; public class Employee { private Integer i ...
- 解锁用户scott并授权
请输入用户名: system 输入口令: 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Producti ...
- 超详细!盘点Python中字符串的常用操作
在Python中字符串的表达方式有四种 一对单引号 一对双引号 一对三个单引号 一对三个双引号 a = 'abc' b= "abc" c = '''abc''' d = " ...
- xss构造--如何使用xss语句
XSS的构造 1.利用[<>]构造html/js 如[<script>alert(/xss/)</script>] 2.伪协议 使用javascript:伪协议来构 ...
- css3 压缩及验证工具
1.css w3c统一验证工具 网址:http://www.csstats.com/ 如果你想要更全面的,这个神奇,你值得拥有: w3c统一验证工具:http://validator.w3.org/u ...
- spring mvc(4) HandlerMapping
在前面一节里提到,DispatcherServlet在接收到请求后,通过HandlerMapping找到处理请求对应的Controller(其实处理请求器并不一定是Controller,还可以是Htt ...
- Python爬虫之反爬虫---使用随机User-Agent
在编写爬虫时,大多数情况下,需要设置请求头.而在请求头中,随机更换User-Agent可以避免触发相应的反爬机制. 使用第三方库fake-useragent便可轻松生成随机User-Agent. 使用 ...