http://wikioi.com/problem/1913/

如果本题没有询问2和3,那么本题和蚯蚓那题一模一样。http://www.cnblogs.com/iwtwiioi/p/3935039.html

我们来分析询问2和3。

首先,询问2允许重复经过点。我们想想询问1的做法,是拆点,为什么?因为要控制只走一次。so,询问2就将拆的点去掉就行了。重构一次图,将上边的点向下连边,容量为1,费用为下边那个点的权值。然后现在还有第一行的点没有构造,那么将源连边到第一行的点,和之前相同,容量为1,费用为这些点的权值。接下来我们连最后一行到汇,因为可以允许重复点,那么就将容量设为oo,费用为0。(为什么这样不会走重复边呢?容量为1当然不会重复走。。)

然后我们来看询问3,只是在2的基础上加了个允许边重复。哈哈,重复边还不简单,将中间连的那些边容量全部设为oo,只不过在源连的边容量要为1,因为要限制次数。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cmath>
  4. #include <string>
  5. #include <iostream>
  6. #include <algorithm>
  7. using namespace std;
  8. #define rep(i, n) for(int i=0; i<(n); ++i)
  9. #define for1(i,a,n) for(int i=(a);i<=(n);++i)
  10. #define for2(i,a,n) for(int i=(a);i<(n);++i)
  11. #define for3(i,a,n) for(int i=(a);i>=(n);--i)
  12. #define for4(i,a,n) for(int i=(a);i>(n);--i)
  13. #define CC(i,a) memset(i,a,sizeof(i))
  14. #define read(a) a=getint()
  15. #define print(a) printf("%d", a)
  16. #define dbg(x) cout << #x << " = " << x << endl
  17. #define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }
  18. inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }
  19. inline const int max(const int &a, const int &b) { return a>b?a:b; }
  20. inline const int min(const int &a, const int &b) { return a<b?a:b; }
  21.  
  22. const int N=5500, M=2000000, oo=~0u>>1, s=0, t=5200, ss=t+1, tt=ss+1;
  23. int ihead[N], cnt=1, d[N], p[N], n, m, vis[N], q[N], front, tail, id[35][70], nd[35][70];
  24. struct ED { int from, to, cap, w, next; } e[M];
  25. inline void add(const int &u, const int &v, const int &c, const int &w) {
  26. e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v; e[cnt].from=u; e[cnt].cap=c; e[cnt].w=w;
  27. e[++cnt].next=ihead[v]; ihead[v]=cnt; e[cnt].to=u; e[cnt].from=v; e[cnt].cap=0; e[cnt].w=-w;
  28. }
  29. inline const bool spfa(const int &s, const int &t) {
  30. for1(i, 0, t) d[i]=1000000000, vis[i]=0;
  31. vis[s]=1; d[s]=front=tail=0; q[tail++]=s;
  32. int u, v, i;
  33. while(front!=tail) {
  34. u=q[front++]; if(front==N) front=0;
  35. for(i=ihead[u]; i; i=e[i].next) if(e[i].cap && d[v=e[i].to]>d[u]+e[i].w) {
  36. d[v]=d[u]+e[i].w; p[v]=i;
  37. if(!vis[v]) {
  38. vis[v]=1, q[tail++]=v;
  39. if(tail==N) tail=0;
  40. }
  41. }
  42. vis[u]=0;
  43. }
  44. return d[t]!=1000000000;
  45. }
  46. int mcf(const int &s, const int &t) {
  47. int ret=0, f, u;
  48. while(spfa(s, t)) {
  49. for(f=oo, u=t; u!=s; u=e[p[u]].from) f=min(f, e[p[u]].cap);
  50. for(u=t; u!=s; u=e[p[u]].from) e[p[u]].cap-=f, e[p[u]^1].cap+=f;
  51. ret+=d[t]*f;
  52. }
  53. return ret;
  54. }
  55. void rebuild() {
  56. CC(ihead, 0); cnt=1; int now;
  57. for1(i, 1, n) for1(j, 1, m+i-1) {
  58. now=id[i][j];
  59. if(i<n) add(now, id[i+1][j], 1, -nd[i+1][j]), add(now, id[i+1][j+1], 1, -nd[i+1][j+1]);
  60. }
  61. for1(j, 1, m) add(s, id[1][j], 1, -nd[1][j]);
  62. for1(j, 1, m+n-1) add(id[n][j], t, oo, 0);
  63. add(ss, s, oo, 0); add(t, tt, oo, 0);
  64. }
  65. int main() {
  66. read(m); read(n);
  67. int c, now, tot=0, pw=(n+m-1)*(n+m-1);
  68. for1(i, 1, n) for1(j, 1, m+i-1) id[i][j]=++tot;
  69. for1(i, 1, n) for1(j, 1, m+i-1) {
  70. read(c); now=id[i][j]; nd[i][j]=c;
  71. add(now, now+pw, 1, -c);
  72. if(i<n) add(now+pw, id[i+1][j], 1, 0), add(now+pw, id[i+1][j+1], 1, 0);
  73. }
  74. for1(j, 1, m) add(s, id[1][j], 1, 0);
  75. for1(j, 1, m+n-1) add(id[n][j]+pw, t, 1, 0);
  76. add(ss, s, m, 0); add(t, tt, m, 0);
  77. printf("%d\n", -mcf(ss, tt));
  78.  
  79. //case 2
  80. rebuild();
  81. printf("%d\n", -mcf(ss, tt));
  82.  
  83. //case 3
  84. for(int i=2, tot=cnt; i<=tot; i+=2) if(e[i].from!=s) e[i].cap=oo, e[i^1].cap=0; else e[i].cap=1, e[i^1].cap=0;
  85. printf("%d\n", -mcf(ss, tt));
  86.  
  87. return 0;
  88. }

题目描述 Description

给定一个由n 行数字组成的数字梯形如下图所示。梯形的第一行有m 个数字。从梯形
的顶部的m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶
至底的路径。
规则1:从梯形的顶至底的m条路径互不相交。
规则2:从梯形的顶至底的m条路径仅在数字结点处相交。
规则3:从梯形的顶至底的m条路径允许在数字结点相交或边相交。

对于给定的数字梯形,分别按照规则1,规则2,和规则3 计算出从梯形的顶至底的m
条路径,使这m条路径经过的数字总和最大。

输入描述
Input Description

第1 行中有2个正整数m和n(m,n<=20),分别
表示数字梯形的第一行有m个数字,共有n 行。接下来的n 行是数字梯形中各行的数字。
第1 行有m个数字,第2 行有m+1 个数字,…。

输出描述
Output Description

将按照规则1,规则2,和规则3 计算出的最大数字总和输出

样例输入
Sample Input

每行一个最大总和。

样例输出
Sample Output

2 5
2 3
3 4 5
9 10 9 1
1 1 10 1 1
1 1 10 12 1 1

数据范围及提示
Data Size & Hint

66
75
77

【wikioi】1913 数字梯形问题(费用流)的更多相关文章

  1. codevs 1913 数字梯形问题 费用流

    题目链接 给你一个数字梯形, 最上面一层m个数字, 然后m+1,......m+n-1个. n是层数. 在每个位置, 可以向左下或右下走.然后让你从最顶端的m个数字开始, 走出m条路径, 使得路过的数 ...

  2. 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)

    传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...

  3. 洛谷P4013 数字梯形问题(费用流)

    题意 $N$行的矩阵,第一行有$M$个元素,第$i$行有$M + i - 1$个元素 问在三个规则下怎么取使得权值最大 Sol 我只会第一问qwq.. 因为有数量的限制,考虑拆点建图,把每个点拆为$a ...

  4. 【bzoj4514】: [Sdoi2016]数字配对 图论-费用流

    [bzoj4514]: [Sdoi2016]数字配对 好像正常的做法是建二分图? 我的是拆点然后 S->i cap=b[i] cost=0 i'->T cap=b[i] cost=0 然后 ...

  5. 【BZOJ4514】数字配对(费用流)

    题意: 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci× ...

  6. bzoj4514: [Sdoi2016]数字配对(费用流)

    传送门 ps:费用流增广的时候费用和流量打反了……调了一个多小时 每个数只能参与一次配对,那么这就是一个匹配嘛 我们先把每个数分解质因数,记质因子总个数为$cnt_i$,那如果$a_i/a_j$是质数 ...

  7. [SDOI2016]数字配对(费用流+贪心+trick)

    重点是如何找到可以配对的\(a[i]\)和\(a[j]\). 把\(a[i]\)分解质因数.设\(a[i]\)分解出的质因数的数量为\(cnt[i]\). 设\(a[i]\geq a[j]\) 那么\ ...

  8. BZOJ4514 [Sdoi2016]数字配对 【费用流】

    题目 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 ai/aj 是一个质数, 那么这两个数字可以配对,并获得 ci×c ...

  9. wikioi 1035 火车停留 裸费用流

    链接:http://wikioi.com/problem/1035/ 怎么说呢,只能说这个建图很有意思.因为只有m条道,然后能互相接在一起的连通,对每个点进行拆点,很有意思的一道裸费用留题. 代码: ...

随机推荐

  1. Centos镜像使用帮助

    https://lug.ustc.edu.cn/wiki/mirrors/help/centos

  2. jQuery 效果函数

    jQuery 效果函数 方法 描述 animate() 对被选元素应用“自定义”的动画 clearQueue() 对被选元素移除所有排队的函数(仍未运行的) delay() 对被选元素的所有排队函数( ...

  3. Encode and Decode Strings

    Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...

  4. 【转】maven仓库快速镜像

    本文转自:http://blog.csdn.net/zuoluoboy/article/details/20007819 国内连接maven官方的仓库更新依赖库,网速一般很慢,收集一些国内快速的mav ...

  5. 当年的文曲星cc800

    你还记得当年的cc800吗?还记得黄金英雄传说吗?还记得用cc800编程的日子吗... 今天突然想起了我的cc800,好怀念那段爬在家里的阳台的木架子上,挠着头,编程序的日子...可惜,当时比较穷,没 ...

  6. svn 切换默认用户名

    2015年1月19日 15:37:30\ 原文: http://www.2cto.com/os/201307/229325.html linux svn切换用户   1. 临时切换   在所有命令下强 ...

  7. windows下安装coreseek/sphinx

    2013年12月8日 17:26:26 注意的地方: 1.配置文件的 数据源, 索引, 服务 这3处配置的路径要写成windows识别的路径,最好是绝对路径 2.安装windows服务的时候,可以不带 ...

  8. HDU 1452 Happy 2004 (逆元+快速幂+积性函数)

    G - Happy 2004 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm ...

  9. Java问题排查工具箱[转载]

    转载自:http://hellojava.info/?p=517 作者:阿里毕玄 问题排查除了最重要的解决思路和逻辑推导能力外,工具也是不可缺少的一部分,一个好用的工具可以事半功倍,甚至在某些情况下会 ...

  10. MVC模式简介

    MVC模式是一种表现模式,它将web应用程序分成三个主要部分即:模型(Model)视图(View)控制器(Controller)M:Model主要是存储或者是处理数据的模型,包含了用户使用的数据,业务 ...