P1361 小M的作物

题目描述

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

现在,第\(i\)种作物种植在\(A\)中种植可以获得\(a_i\)的收益,在\(B\)中种植可以获得\(b_i\)的收益,而且,现在还有这么一种神奇的现象,就是某些作物共同种在一块耕地中可以获得额外的收益,小\(M\)找到了规则中共有\(m\)种作物组合,第\(i\)个组合中的作物共同种在\(A\)中可以获得\(c1_i\)的额外收益,共同总在B中可以获得\(c2_i\)的额外收益。

小M很快的算出了种植的最大收益,但是他想要考考你,你能回答他这个问题么?

输入输出格式

输入格式:

第一行包括一个整数\(n\)

第二行包括\(n\)个整数,表示\(a_i\)第三行包括\(n\)个整数,表示\(b_i\)第四行包括一个整数\(m\)接下来\(m\)行,

对于接下来的第\(i\)行:第一个整数\(k_i\),表示第\(i\)个作物组合中共有\(k_i\)种作物,

接下来两个整数\(c1_i\),\(c2_i\),接下来\(k_i\)个整数,表示该组合中的作物编号。

输出格式:

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

数据范围

1<=k< n<= 1000,0 < m < = 1000 保证所有数据及结果不超过\(2*10^9\)。


这个题加深了我对最小割模型的理解。

我第一点弄明白的一点,也是最重要的一点。

最小割在数值上与最大流相等,但在本身性质上与网络流无任何关系。

它的不那么准确的定义是:在一个图中,割去权值和最小的边集,使这个图分成两个部分,切下来的那一刀叫做最小割。最小割并不唯一,但它在数值上是等于最大流的

对于这个题的模型来说,它有一个名字叫做二者取一式问题,在具体题目中的体现即为把点集一分为二。

类似的题目有善意的投票

虽然说了最小割与网络流无关系,但只是在定义或者说是意义上,真正要到建模时,还需要将两者综合考虑。

先考虑没有额外收益情况下的建图。

设源点S属于集合A,汇点T属于集合B,则显然点与源点所连的有向边为这个点归属于集合A所产生的收益,与汇点相连则同理。则原图边权之和-最小割就是本题的答案了。

在这个图的基础上,考虑如何把点集给加入。

首先明确一点,点集的贡献有三种情况,对集合A贡献,对集合B贡献或者不贡献。这意味着只划分出一种状态是无法描述的,至少要把A与B的情况分开描述。

讨论一个对\(A\)有贡献的点集\(\{c,d\}\)。

依据题目,我们对这个点集的要求是,只要\(c,d\)有一个点被割到了集合\(T\),这个点集都无法产生贡献。换而言之,只要\(c\)或\(d\)在集合\(B\),代表点集贡献的边必须要断开。

先尝试着连接这条贡献边,因为这条边不可能直接连到图中代表作物的点上,所以连接一个虚点上去。

X为点集所产生的虚点。

如果\(c\)被割到了集合\(B\),则所有从\(S\)到\(c\)的路径都得被断开(具体只路径的一条边断掉),如果我们想要黄边断掉,那么虚点\(X\)连\(c\)的那条路径不能被断掉。而容量为正无穷的边不可能被断掉,于是我们这样建图。

两条蓝色的边的边权为\(inf\)

对待贡献\(B\)集合的点,同理

建图跑网络流即可。

要注意的一点是,这题卡常,吸氧才水过去的


Code

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=3010;
const int M=2000100;
const int inf=0x3f3f3f3f;
int head[N],edge[M],to[M],next[M],cnt=1;
void add(int u,int v,int w)
{
to[++cnt]=v;next[cnt]=head[u];edge[cnt]=w;head[u]=cnt;
to[++cnt]=u;next[cnt]=head[v];edge[cnt]=0;head[v]=cnt;
}
int dep[N],used[N],pre[N],tot,s[N],ans,m,n,sum;
queue <int > q;
bool bfs()
{
while(!q.empty()) q.pop();
q.push(0);
memset(dep,0,sizeof(dep));
dep[0]=1;
while(!q.empty()&&q.front()!=n+1)
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=next[i])
{
int v=to[i],w=edge[i];
if(!dep[v]&&w)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return !q.empty();
}
int main()
{
scanf("%d",&n);
int w,v,k,c1,c2;
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
sum+=w;
add(0,i,w);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&w);
sum+=w;
add(i,n+1,w);
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&k,&c1,&c2);
add(0,i+n+1,c1);sum+=c1;
add(i+n+m+1,n+1,c2);sum+=c2;
for(int j=1;j<=k;j++)
{
scanf("%d",&v);
add(i+n+1,v,inf);
add(v,i+n+m+1,inf);
}
}
while(bfs())
{
memset(used,0,sizeof(used));
s[++tot]=0;
while(tot)
{
int u=s[tot];
if(u==n+1)
{
int mi=inf,id;
for(int i=tot;i>1;i--)
if(mi>=edge[pre[s[i]]])
{
mi=edge[pre[s[i]]];
id=i;
}
ans+=mi;
for(int i=tot;i>1;i--)
{
edge[pre[s[i]]]-=mi;
edge[pre[s[i]]^1]+=mi;
}
tot=id-1;
used[n+1]=0;
}
else
{
for(int i=head[u];i;i=next[i])
{
int v=to[i],w=edge[i];
if(!used[v]&&dep[v]==dep[u]+1&&w)
{
used[v]=1;
s[++tot]=v;
pre[v]=i;
break;
}
}
if(u==s[tot]) tot--;
}
}
}
printf("%d\n",sum-ans);
return 0;
}

2018.6.28

洛谷 P1361 小M的作物 解题报告的更多相关文章

  1. [洛谷P1361]小M的作物

    题目大意:将作物种在A,B两地,对于每种作物,种A,B分别有不同的收益,对于一些特殊的作物集合,共同种到A,B集合分别有一些额外收益.求最大收益. 题解:最小割,S向i连容量为$a_i$的边,i向T连 ...

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

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

  3. [BZOJ3438][洛谷P1361]小M的作物

    题目大意:有A.B两个集合和n个物品,每个物品只能放在一个集合里.每个物品放在不同集合内能获得不同价值.有一些物品,如果它们同时放在一个集合内,则会产生新的价值(A和B中都有且不一定相同(c1和c2) ...

  4. 洛谷 P1993 小K的农场 解题报告

    P1993 小K的农场 题目描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述: 农场a比农场b ...

  5. 洛谷 P2323 [HNOI2006]公路修建问题 解题报告

    P2323 [HNOI2006]公路修建问题 题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 思路: 二分答案 然后把每条能加的大边都加上,然后加小边 但在洛谷的题 ...

  6. 洛谷 P3299 [SDOI2013]保护出题人 解题报告

    P3299 [SDOI2013]保护出题人 题目描述 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企 ...

  7. 洛谷 P1377 [TJOI2011]树的序 解题报告

    P1377 [TJOI2011]树的序 题目描述 众所周知,二叉查找树的形态和键值的插入顺序密切相关.准确的讲:1.空树中加入一个键值\(k\),则变为只有一个结点的二叉查找树,此结点的键值即为\(k ...

  8. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

  9. 洛谷 P2527 [SHOI2001]Panda的烦恼 解题报告

    P2527 [SHOI2001]Panda的烦恼 题目描述 panda是个数学怪人,他非常喜欢研究跟别人相反的事情.最近他正在研究筛法,众所周知,对一个范围内的整数,经过筛法处理以后,剩下的全部都是质 ...

随机推荐

  1. 20155206 Exp2 后门原理与实践

    20155206 Exp2 后门原理与实践 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机IP 然后使用ncat.exe程序,ncat. ...

  2. 20155302《网络对抗》Exp3 免杀原理与实践

    20155302<网络对抗>Exp3 免杀原理与实践 实验要求 1.正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编 ...

  3. 【第三课】Centos 7.x系统安装和网络配置以及远程密钥登录

    目录 一.安装CentOS 7.3 二.配置网络 1.使用dhclient命令自动获取ip地址 2.使用ip addr或ifconfig命令查看网卡信息 3.使用route命令查看路由信息 4.通过修 ...

  4. HashMap 源码解析(一)之使用、构造以及计算容量

    目录 简介 集合和映射 HashMap 特点 使用 构造 相关属性 构造方法 tableSizeFor 函数 一般的算法(效率低, 不值得借鉴) tableSizeFor 函数算法 效率比较 tabl ...

  5. [Mark]Tomcat/IIS 更改 HTTP 侦听端口

    目的: IIS HTTP 侦听端口改为 8088 Tomcat HTTP 侦听端口改为 80 环境: Windows Server 2012 R2 IIS8.5 (默认端口是 80) Tomcat8. ...

  6. 【ORACLE】oracle打补丁

    -- 备份旧的opatch cd $ORACLE_HOME/ mv OPatch  OPatch_20180323_old -- 上传补丁工具和补丁包到oraclehome目录下,解压 unzip p ...

  7. vsftp在防火墙开启需要开放的端口

    1.开放tcp端口 firewall-cmd --zone=public --add-port=20/tcp --permanent firewall-cmd --zone=public --add- ...

  8. Jenkins Maven安装设置

    Jenkins Maven安装设置 如果没有学习过 Maven 的朋友,可以先了解 Maven教程,然后再进一步学习本教程文章. 第1步:下载和设置Maven Maven的官方网站就是Apache M ...

  9. 高可用Kubernetes集群-14. 部署Kubernetes集群性能监控平台

    参考文档: Github介绍:https://github.com/kubernetes/heapster Github yaml文件: https://github.com/kubernetes/h ...

  10. p4语言编程环境安装

    p4语言主要是用来模拟交换机的交互,是新一代的SDN解决方案,可以让数据转发平面也具有可编程能力,让软件能够真正定义网络和网络设备.详细介绍 主要流程是:安装vmware.安装Ubuntu.下载Git ...