题目描述:这里

极其裸的一道费用流问题

首先分析第一问,由于要求一个点只能经过一次,所以我们将梯形中的每一个点拆成两个点(记为入点和出点,顾名思义,入点用来承接上一行向这一行的边,出点用来向下一行连边)

然后将出入点之间的流量设为1,边权设为0,这样就有效保证了一个点只经过一次

接下来,我们从上一行的出点向下一行的入点连边,容量为1,费用为下一行对应点的代价的相反数,然后建起超级源点与超级终点,分别向第一行的入点连边,容量1费用0,由最后一行出点向终点连边,容量1费用0,跑一遍费用流即可(就是套路的最大费用流)

然后看第二问,发现点可以重复经过,这样就不用拆点了,但边不能重复走,所以我们不拆点,剩下的建边与上面相同

但是注意:两条路径可以相交于最后一行,这样的话如果最后一行的点向汇点连边的容量为1是不够的,所以设的容量要大于等于2

第三问就是把除了源点到第一行的边以外的边边权全改为正无穷即可

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <stack>
  9. #define ll long long
  10. using namespace std;
  11. const ll inf=0x3f3f3f3f3f3f3f3fll;
  12. struct Edge
  13. {
  14. int next;
  15. int to;
  16. ll val;
  17. ll pri;
  18. }edge[];
  19. int head[];
  20. int nnum[][];
  21. ll a[][];
  22. ll dis[];
  23. int pre[];
  24. int fa[];
  25. ll lim[];
  26. bool used[];
  27. int cnt=;
  28. int tot=;
  29. int st,ed;
  30. int n,m;
  31. void init()
  32. {
  33. memset(edge,,sizeof(edge));
  34. memset(head,-,sizeof(head));
  35. cnt=;
  36. }
  37. void add(int l,int r,ll w,ll v)
  38. {
  39. edge[cnt].next=head[l];
  40. edge[cnt].to=r;
  41. edge[cnt].val=w;
  42. edge[cnt].pri=v;
  43. head[l]=cnt++;
  44. }
  45. int ide(int x)
  46. {
  47. return (x&)?x+:x-;
  48. }
  49. bool spfa()
  50. {
  51. memset(dis,0x3f,sizeof(dis));
  52. memset(lim,,sizeof(lim));
  53. memset(used,,sizeof(used));
  54. used[st]=;
  55. lim[st]=inf;
  56. dis[st]=;
  57. pre[ed]=-;
  58. queue <int> M;
  59. M.push(st);
  60. while(!M.empty())
  61. {
  62. int u=M.front();
  63. M.pop();
  64. for(int i=head[u];i!=-;i=edge[i].next)
  65. {
  66. int to=edge[i].to;
  67. if(edge[i].val&&dis[to]>dis[u]+edge[i].pri)
  68. {
  69. dis[to]=dis[u]+edge[i].pri;
  70. lim[to]=min(lim[u],edge[i].val);
  71. pre[to]=i,fa[to]=u;
  72. if(!used[to])used[to]=,M.push(to);
  73. }
  74. }
  75. used[u]=;
  76. }
  77. return pre[ed]!=-;
  78. }
  79. ll EK()
  80. {
  81. ll maxw=,minv=;
  82. while(spfa())
  83. {
  84. maxw+=lim[ed];
  85. minv+=dis[ed]*lim[ed];
  86. int temp=ed;
  87. while(temp!=st)
  88. {
  89. edge[pre[temp]].val-=lim[ed];
  90. edge[ide(pre[temp])].val+=lim[ed];
  91. temp=fa[temp];
  92. }
  93. }
  94. return minv;
  95. }
  96. int main()
  97. {
  98. scanf("%d%d",&m,&n);
  99. init();
  100. st=,ed=;
  101. for(int i=;i<=n;i++)
  102. {
  103. for(int j=;j<=m+i-;j++)
  104. {
  105. scanf("%lld",&a[i][j]);
  106. nnum[i][j]=++tot;
  107. }
  108. }
  109. for(int i=;i<=n;i++)
  110. {
  111. for(int j=;j<=m+i-;j++)
  112. {
  113. add(nnum[i][j]<<,(nnum[i][j]<<)|,,-a[i][j]);
  114. add((nnum[i][j]<<)|,nnum[i][j]<<,,a[i][j]);
  115. if(i==)
  116. {
  117. add(st,nnum[i][j]<<,,);
  118. add(nnum[i][j]<<,st,,);
  119. }
  120. if(i==n)
  121. {
  122. add((nnum[i][j]<<)|,ed,,);
  123. add(ed,(nnum[i][j]<<)|,,);
  124. }else
  125. {
  126. add((nnum[i][j]<<)|,(nnum[i+][j]<<),,);
  127. add((nnum[i+][j]<<),(nnum[i][j]<<)|,,);
  128. add((nnum[i][j]<<)|,(nnum[i+][j+]<<),,);
  129. add((nnum[i+][j+]<<),(nnum[i][j]<<)|,,);
  130. }
  131. }
  132. }
  133. printf("%lld\n",-EK());
  134. init();
  135. for(int i=;i<=n;i++)
  136. {
  137. for(int j=;j<=m+i-;j++)
  138. {
  139. if(i==)
  140. {
  141. add(st,nnum[i][j]+,,-a[i][j]);
  142. add(nnum[i][j]+,st,,a[i][j]);
  143. }
  144. if(i==n)
  145. {
  146. add(nnum[i][j]+,ed,,);
  147. add(ed,nnum[i][j]+,,);
  148. }else
  149. {
  150. add(nnum[i][j]+,nnum[i+][j]+,,-a[i+][j]);
  151. add(nnum[i+][j]+,nnum[i][j]+,,a[i+][j]);
  152. add(nnum[i][j]+,nnum[i+][j+]+,,-a[i+][j+]);
  153. add(nnum[i+][j+]+,nnum[i][j]+,,a[i+][j+]);
  154. }
  155. }
  156. }
  157. printf("%lld\n",-EK());
  158. init();
  159. for(int i=;i<=n;i++)
  160. {
  161. for(int j=;j<=m+i-;j++)
  162. {
  163. if(i==)
  164. {
  165. add(st,nnum[i][j]+,,-a[i][j]);
  166. add(nnum[i][j]+,st,,a[i][j]);
  167. }
  168. if(i==n)
  169. {
  170. add(nnum[i][j]+,ed,inf,);
  171. add(ed,nnum[i][j]+,,);
  172. }else
  173. {
  174. add(nnum[i][j]+,nnum[i+][j]+,inf,-a[i+][j]);
  175. add(nnum[i+][j]+,nnum[i][j]+,,a[i+][j]);
  176. add(nnum[i][j]+,nnum[i+][j+]+,inf,-a[i+][j+]);
  177. add(nnum[i+][j+]+,nnum[i][j]+,,a[i+][j+]);
  178. }
  179. }
  180. }
  181. printf("%lld\n",-EK());
  182. return ;
  183. }

网络流24题——数字梯形问题 luogu 4013的更多相关文章

  1. COGS738 [网络流24题] 数字梯形(最小费用最大流)

    题目这么说: 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径.规则1:从梯形的 ...

  2. Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算)

    Libre 6009 「网络流 24 题」软件补丁 / Luogu 2761 软件安装问题 (最短路径,位运算) Description T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放 ...

  3. Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流)

    Libre 6006 「网络流 24 题」试题库 / Luogu 2763 试题库问题 (网络流,最大流) Description 问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同 ...

  4. 网络流24题——魔术球问题 luogu 2765

    题目描述:这里 这道题是网络流问题中第一个难点,也是一个很重要的问题 如果直接建图感觉无从下手,因为如果不知道放几个球我就无法得知该如何建图(这是很显然的,比如我知道 $1+48=49=7^2$ ,可 ...

  5. 网络流24题——试题库问题 luogu 2763

    题目描述看:这里 这是我们遇到的第一个要求输出方案的问题 考虑建图然后用最大流思想: 首先由源点向每一道试题连边,容量为1 然后由每一种试题类型向汇点连边,容量为需求量 最后由每一道试题向可能属于的试 ...

  6. 网络流24题——骑士共存问题 luogu 3355

    题目描述:这里 从这里开始,我们涉及到了一个新的问题:最小割问题 首先给出一些定义(本人根据定义自己口胡的): 一个流网络中的一个割是一个边集,使得割掉这些边集后源点与汇点不连通 而最小割问题就是一个 ...

  7. Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)

    Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...

  8. LOJ #6010. 「网络流 24 题」数字梯形

    #6010. 「网络流 24 题」数字梯形   题目描述 给定一个由 n nn 行数字组成的数字梯形如下图所示.梯形的第一行有 m mm 个数字.从梯形的顶部的 m mm 个数字开始,在每个数字处可以 ...

  9. Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流)

    Libre 6007 「网络流 24 题」方格取数 / Luogu 2774 方格取数问题 (网络流,最大流) Description 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从 ...

随机推荐

  1. 前端动态菜单-bootstrap-treeview

    一.bootstrap-treeview 官网 Demo bootstrap-treeview是一款效果非常酷的基于bootstrap的jQuery多级列表树插件.该jQuery插件基于Twitter ...

  2. django-haystack全文检索

    一:使用的工具haystack是django的开源搜索框架,该框架支持Solr,Elasticsearch,Whoosh, *Xapian*搜索引擎,不用更改代码,直接切换引擎,减少代码量.搜索引擎使 ...

  3. xadmin 数据添加报错: IndexError: list index out of range

    报错现象 xadmin 集成到项目后进行添加数据的时候报错 具体如下 黄页 后端 具体报错定位 报错分析 点击这里 报错解决 源码 input_html = [ht for ht in super(A ...

  4. 执行Git命令时出现各种 SSL certificate problem 的解决办法

    执行Git命令时出现各种 SSL certificate problem 的解决办法 来源  https://www.cnblogs.com/chenzc/p/5842932.html 比如我在win ...

  5. python学习日记(正则表达式)

    定义 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Pyth ...

  6. CC++语法::数组名退化(array decaying)

    参考: CSDN::C/C++中数组名退化为指针的情况 stackoverflow::What is array decaying? 起因 笔者在写memset的时候总想偷一点懒(因为我们一般都是为了 ...

  7. qt 视频播放器错误解决方法

    DirectShowPlayerService::doRender: Unresolved error code 0x80040266 () 当你发布的qmlproject包含QtMultimedia ...

  8. MUI框架 按钮点击响应不好的问题解决办法

    MUI框架 按钮点击响应不好的问题 实际例子: $(function (){ mui(document.body).on('tap', '.bindchk', function(e) { //触发一次 ...

  9. BAT面试经验分享——iOS高级开发工程师的自我总结!

    序言 目前形势,参加到iOS队伍的人是越来越多,甚至已经到供过于求了. 今年,找过工作人可能会更深刻地体会到今年的就业形势不容乐观,随着各大公司秋招的开始,很多小伙伴都行动起来了,我也有幸获得了一份不 ...

  10. vue引入fastclick设置输入框type="number"报错Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('number') does not support selection.的解决办法

    将输入框type设为text,通过正则验证输入的值