题目戳我

\(\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的作物的更多相关文章

  1. 善意的投票&小M的作物 题解

    善意的投票: 因为只有\(2\)种意愿,不妨让想睡午觉的和源点连边,让不想睡午觉的和汇点连边.对于每一对好朋友,在他们之间连边.那么只要源点和汇点还联通,就存在一对好友是冲突的,我们现在要做的就是删去 ...

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

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

  3. BZOJ 3438 小M的作物 & BZOJ 1877 [SDOI2009]晨跑

    我由衷地为我的朋友高兴.哈哈,yian,当你nick name破百上千时,再打“蒟蒻”就会被打的. 好的,说正事吧.请注意,这还是题解.但我发现,网络流实在是太套路了(怪不得这两年几乎销声匿迹).我们 ...

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

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

  5. luogu P1361 小M的作物

    题目链接 luogu P1361 小M的作物 题解 源汇点为A,B 向种子连边,容量为价值,每个种子能与A或B联通,考虑最小割 用建边的总流量减去最小割就是答案 相同利益的时候新建节点,由额外利益构成 ...

  6. 「BZOJ3438」小M的作物(最小割

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

  7. bzoj3438: 小M的作物(那年花开最小割)

    3438: 小M的作物 题目:传送门 题解: 最小割标准水题(做了几天的最小割之后表示是真的水) 为什么水:博主已经做过两道基本一样的题目了... 详情参考:bzoj3894 代码: #include ...

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

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

  9. P1361 小M的作物

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

  10. BZOJ_3438_小M的作物_最小割

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

随机推荐

  1. Android-PullToRefresh上拉下拉刷新加载更多,以及gridview刷新功能的Library下载地址

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985,转载请说明出处. 首先大家应该都听说过此开源框架的强大之处,支持单列以及双列的 上拉加载以及下拉刷新功 ...

  2. zabbix如何监控Nvidia显卡的各项指标?

    如何实现zabbix监控windows机器的N卡GPU指标呢? Nvidia卡在安装驱动程序的时候,已经自带安装了一个命令行工具来获取显卡的各个性能指标值 在windows机器上,我们可以把该路径加入 ...

  3. php 循环里面套sql怎么解决

    功能要求: 企业列表(展示企业的基本信息,这里只获取了名称.logo.和服务类型), 服务类型说明: 服务类型一共3级,1.2级是必填的,3级是非必填,如果填的话最多3个, 服务类型1.2.3保存在一 ...

  4. Macos 编译运行调试Mysql源代码

    准备编译工具Clion 下载地址 工具是macos用的系统 百度云盘下载地址(密码: 7dus) 下载mysql源码 Mysql源码下载地址 下载boost boost下载地址 前期准备工作 MySQ ...

  5. 编写第一个 .NET 微服务

    介绍 本文的目的是:通过创建一个返回列表的简单服务,并在 Docker 容器中运行该服务,让您熟悉使用 .NET 创建微服务的构建过程. 安装 .NET SDK 要开始构建 .NET 应用程序,首先下 ...

  6. 【IDEA】【SpringBoot】基于idea对springboot程序远程调试

    一.开启远程调试前提:本地代码与服务器代码一致(实测:不关键的代码稍微有点不一样好像也不会有多大问题). 二.开启远程调试步骤 1.开发工具配置 idea端打开Edit configurations, ...

  7. 想要使用GPU进行加速?那你必须事先了解CUDA和cuDNN

    这一期我们来介绍如何在Windows上安装CUDA,使得对图像数据处理的速度大大加快,在正式的下载与安装之前,首先一起学习一下预导知识,让大家知道为什么使用GPU可以加速对图像的处理和计算,以及自己的 ...

  8. shell小技巧(6)修改一批文件后缀

    当前目录下后缀为sh的文件,改为后缀shell. 这里列出两种方法,先看第一种.方法1:#!/bin/bash str=`find ./ -name \*.sh`  # 会产生一个列表 file=&q ...

  9. Oracle数据库之体系结构

    Oracle数据库管理系统中的3个重要的概念:实例(Instance).数据库(Database)和数据库服务器(Database Server). 实例:是后台进程和内存结构的集合,是Oracle数 ...

  10. [PyTorch 学习笔记] 7.1 模型保存与加载

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson7/model_save.py https://githu ...