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

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5. const int N=3010;
  6. const int M=2000100;
  7. const int inf=0x3f3f3f3f;
  8. int head[N],edge[M],to[M],next[M],cnt=1;
  9. void add(int u,int v,int w)
  10. {
  11. to[++cnt]=v;next[cnt]=head[u];edge[cnt]=w;head[u]=cnt;
  12. to[++cnt]=u;next[cnt]=head[v];edge[cnt]=0;head[v]=cnt;
  13. }
  14. int dep[N],used[N],pre[N],tot,s[N],ans,m,n,sum;
  15. queue <int > q;
  16. bool bfs()
  17. {
  18. while(!q.empty()) q.pop();
  19. q.push(0);
  20. memset(dep,0,sizeof(dep));
  21. dep[0]=1;
  22. while(!q.empty()&&q.front()!=n+1)
  23. {
  24. int u=q.front();
  25. q.pop();
  26. for(int i=head[u];i;i=next[i])
  27. {
  28. int v=to[i],w=edge[i];
  29. if(!dep[v]&&w)
  30. {
  31. dep[v]=dep[u]+1;
  32. q.push(v);
  33. }
  34. }
  35. }
  36. return !q.empty();
  37. }
  38. int main()
  39. {
  40. scanf("%d",&n);
  41. int w,v,k,c1,c2;
  42. for(int i=1;i<=n;i++)
  43. {
  44. scanf("%d",&w);
  45. sum+=w;
  46. add(0,i,w);
  47. }
  48. for(int i=1;i<=n;i++)
  49. {
  50. scanf("%d",&w);
  51. sum+=w;
  52. add(i,n+1,w);
  53. }
  54. scanf("%d",&m);
  55. for(int i=1;i<=m;i++)
  56. {
  57. scanf("%d%d%d",&k,&c1,&c2);
  58. add(0,i+n+1,c1);sum+=c1;
  59. add(i+n+m+1,n+1,c2);sum+=c2;
  60. for(int j=1;j<=k;j++)
  61. {
  62. scanf("%d",&v);
  63. add(i+n+1,v,inf);
  64. add(v,i+n+m+1,inf);
  65. }
  66. }
  67. while(bfs())
  68. {
  69. memset(used,0,sizeof(used));
  70. s[++tot]=0;
  71. while(tot)
  72. {
  73. int u=s[tot];
  74. if(u==n+1)
  75. {
  76. int mi=inf,id;
  77. for(int i=tot;i>1;i--)
  78. if(mi>=edge[pre[s[i]]])
  79. {
  80. mi=edge[pre[s[i]]];
  81. id=i;
  82. }
  83. ans+=mi;
  84. for(int i=tot;i>1;i--)
  85. {
  86. edge[pre[s[i]]]-=mi;
  87. edge[pre[s[i]]^1]+=mi;
  88. }
  89. tot=id-1;
  90. used[n+1]=0;
  91. }
  92. else
  93. {
  94. for(int i=head[u];i;i=next[i])
  95. {
  96. int v=to[i],w=edge[i];
  97. if(!used[v]&&dep[v]==dep[u]+1&&w)
  98. {
  99. used[v]=1;
  100. s[++tot]=v;
  101. pre[v]=i;
  102. break;
  103. }
  104. }
  105. if(u==s[tot]) tot--;
  106. }
  107. }
  108. }
  109. printf("%d\n",sum-ans);
  110. return 0;
  111. }

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. Feeling_2018_5_22

    “我打你,你会走吗?”    “不会!!” “我骂你,你会走吗?”    “不会!!” “那我不爱你了,你会走吗?”       “会.”

  2. WPF Get jiayuan outbox list(send mail box)

      Request URL: http://www.jiayuan.com/msg/outbox/list.php Request Method: POST form data: type=all&a ...

  3. redis系列--深入哨兵集群

    一.前言 在之前的系列文章中介绍了redis的入门.持久化以及复制功能,如果不了解请移步至redis系列进行阅读,当然我也是抱着学习的知识分享,如果有什么问题欢迎指正,也欢迎大家转载.而本次将介绍哨兵 ...

  4. 20155217《网络对抗》Exp03 免杀原理与实践

    20155217<网络对抗>Exp03 免杀原理与实践 实践内容 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,自己利用shellcode编程 ...

  5. WPF编程,自定义鼠标形状的一种方法。

    原文:WPF编程,自定义鼠标形状的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8727 ...

  6. mfc 线程的优先级

    知识点:  线程优先级  获取当前线程句柄  线程优先级设置  线程优先级变动  线程优先级获取 一.线程优先级(Thread priority ) 简单的说就是(线程)的优先级越高,那么就 ...

  7. Maven学习第1期---Maven简单介绍

    前言 Hadoop的MapReduce环境是一个复杂的编程环境,所以我们要尽可能地简化构建MapReduce项目的过程.Maven是一个很不错的自动化项目构建工具,通过Maven来帮助我们从复杂的环境 ...

  8. C语言与数据库操作入门(Win版)

    C语言与数据库操作入门(Win版) 2017年12月10日 17:30:17 阅读数:1387 数据库,DataBase,学C语言的是不是想说,很想爱她却并不容易呢?不用着急,C语言也可以操作数据库的 ...

  9. winform 保存文件 打开文件 选择文件 字体样式颜色(流 using System.IO;)

    string filePath = ""; private void 保存SToolStripMenuItem_Click(object sender, EventArgs e) ...

  10. 《Macro-Micro Adversarial Network for Human Parsing》论文阅读笔记

    <Macro-Micro Adversarial Network for Human Parsing> 摘要:在人体语义分割中,像素级别的分类损失在其低级局部不一致性和高级语义不一致性方面 ...