分层图,建k层,设(i,j,0)为点(i,j)的满油状态,全图的流量都是1,因为重复走到一个点没有意义。如果当前点是加油站,那么它向它上左的点连费用为a的边,向下右连费用为a+b的边;

否则,这个点的所有层向零层连费用为a+c的边表示建加油站和加油,其他的当前点是加油站的情况连即可,但是不用加a。然后s向(1,1,0)连,(n,n)的所有层向t连,最后跑最小费用最大流。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<queue>
  5. #include<algorithm>
  6. #include<map>
  7. using namespace std;
  8. const int N=2000005,inf=1e9;
  9. int n,m,a,b,c,h[N],cnt=1,dis[N],s,t,ans,fr[N],d[105][105],tot,id[105][105][15];
  10. bool v[N];
  11. struct qwe
  12. {
  13. int ne,no,to,va,c;
  14. }e[N<<2];
  15. int read()
  16. {
  17. int r=0,f=1;
  18. char p=getchar();
  19. while(p>'9'||p<'0')
  20. {
  21. if(p=='-')
  22. f=-1;
  23. p=getchar();
  24. }
  25. while(p>='0'&&p<='9')
  26. {
  27. r=r*10+p-48;
  28. p=getchar();
  29. }
  30. return r*f;
  31. }
  32. void add(int u,int v,int w,int c)
  33. {
  34. cnt++;
  35. e[cnt].ne=h[u];
  36. e[cnt].no=u;
  37. e[cnt].to=v;
  38. e[cnt].va=w;
  39. e[cnt].c=c;
  40. h[u]=cnt;
  41. }
  42. void ins(int u,int v,int w,int c)
  43. {
  44. add(u,v,w,c);
  45. add(v,u,0,-c);
  46. }
  47. bool spfa()
  48. {
  49. queue<int>q;
  50. for(int i=s;i<=t;i++)
  51. dis[i]=inf;
  52. dis[s]=0;
  53. v[s]=1;
  54. q.push(s);
  55. while(!q.empty())
  56. {
  57. int u=q.front();
  58. q.pop();
  59. v[u]=0;
  60. for(int i=h[u];i;i=e[i].ne)
  61. if(e[i].va>0&&dis[e[i].to]>dis[u]+e[i].c)
  62. {
  63. dis[e[i].to]=dis[u]+e[i].c;
  64. fr[e[i].to]=i;
  65. if(!v[e[i].to])
  66. {
  67. v[e[i].to]=1;
  68. q.push(e[i].to);
  69. }
  70. }
  71. }
  72. return dis[t]!=inf;
  73. }
  74. void mcf()
  75. {//cout<<"OK"<<endl;
  76. int x=inf;
  77. for(int i=fr[t];i;i=fr[e[i].no])
  78. x=min(x,e[i].va);
  79. for(int i=fr[t];i;i=fr[e[i].no])
  80. {
  81. e[i].va-=x;
  82. e[i^1].va+=x;
  83. ans+=x*e[i].c;
  84. }
  85. }
  86. int main()
  87. {
  88. n=read(),m=read(),a=read(),b=read(),c=read();
  89. for(int i=1;i<=n;i++)
  90. for(int j=1;j<=n;j++)
  91. d[i][j]=read();
  92. for(int i=1;i<=n;i++)
  93. for(int j=1;j<=n;j++)
  94. for(int k=0;k<=m;k++)
  95. id[i][j][k]=++tot;
  96. s=0,t=tot+1;
  97. ins(s,id[1][1][0],1,0);
  98. for(int i=0;i<=m;i++)
  99. ins(id[n][n][i],t,1,0);
  100. for(int i=1;i<=n;i++)
  101. for(int j=1;j<=n;j++)
  102. {
  103. if(d[i][j])
  104. {
  105. for(int k=m-1;k>=0;k--)
  106. {
  107. if(i>1)
  108. ins(id[i-1][j][k],id[i][j][0],1,a);
  109. if(j>1)
  110. ins(id[i][j-1][k],id[i][j][0],1,a);
  111. if(i<n)
  112. ins(id[i+1][j][k],id[i][j][0],1,a+b);
  113. if(j<n)
  114. ins(id[i][j+1][k],id[i][j][0],1,a+b);
  115. }
  116. }
  117. else
  118. {
  119. for(int k=m;k>0;k--)
  120. ins(id[i][j][k],id[i][j][0],1,a+c);
  121. for(int k=m-1;k>=0;k--)
  122. {
  123. if(i>1)
  124. ins(id[i-1][j][k],id[i][j][k+1],1,0);
  125. if(j>1)
  126. ins(id[i][j-1][k],id[i][j][k+1],1,0);
  127. if(i<n)
  128. ins(id[i+1][j][k],id[i][j][k+1],1,b);
  129. if(j<n)
  130. ins(id[i][j+1][k],id[i][j][k+1],1,b);
  131. }
  132. }
  133. }
  134. while(spfa())
  135. mcf();
  136. printf("%d\n",ans);
  137. return 0;
  138. }

洛谷 P4009 汽车加油行驶问题 【最小费用最大流】的更多相关文章

  1. 洛谷 P4009 汽车加油行驶问题 解题报告

    P4009 汽车加油行驶问题 题目描述 给定一个\(N×N\)的方形网格,设其左上角为起点◎,坐标(1,1) ,\(X\)轴向右为正,\(Y\)轴向下为正,每个方格边长为1 ,如图所示. 一辆汽车从起 ...

  2. 洛谷P4009 汽车加油行驶问题

    题目描述 给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示. 一辆汽车从起点◎出发 ...

  3. 洛谷P4009汽车加油行驶问题——网络流24题(最短路)

    题目:https://www.luogu.org/problemnew/show/P4009 网络流24题中不是网络流的最短路题: 把每个点拆成各个油量上的点,根据要求连边即可: 注意:点数最大为10 ...

  4. 洛谷P4009 汽车加油行驶问题(分层最短路)

    传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...

  5. 洛谷 P4016 负载平衡问题 【最小费用最大流】

    求出平均数sum,对于大于sum的点连接(s,i,a[i]-sum,0),表示这个点可以流出多余的部分,对于小于sum的点连接(i,t,sum-a[i],0)表示这个点可以接受少的部分,然后每个点向相 ...

  6. 洛谷 P3381 【【模板】最小费用最大流】

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的 ...

  7. 题解 洛谷 P3381 【【模板】最小费用最大流】

    发了网络流,再来一发费用流 能做费用流的,网络流自然做得来,但在这还是不要脸的安利一下自己的博客(里面也有网络流的题解): 点我 扯远了... 费用流,就是在不炸水管的情况下求源点到汇点的最小费用. ...

  8. 洛谷 P1251 餐巾计划问题【最小费用最大流】

    建图细节比较多,对于每个点i,拆成i和i',i表示用的餐巾,i'表示脏餐巾,连接: (s,i,r[i],p)表示在这一天买新餐巾 (i,t,r[i],0)表示这一天用了r[i]的餐巾 (s,i+n,r ...

  9. P4009 汽车加油行驶问题

    P4009 汽车加油行驶问题 最短路 清一色的spfa....送上一个堆优化Dijkstra吧(貌似代码还挺短) 顺便说一句,堆优化Dj跑分层图灰常好写 #include<iostream> ...

随机推荐

  1. POJ 2391 floyd二分+拆点+最大流

    Ombrophobic Bovines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20904   Accepted: 4 ...

  2. hdu——3861 The King’s Problem

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  3. windows上安装mysql

    安装mysql后 命令行闪退 查看服务 也没有MySQL服务启动 你安装了mysql没有,没有就先安装,安装好mysql以后,在bin目录下有个mysqld.exe,运行这个程序就可以添加mysql服 ...

  4. Spring @Value用法

    Spring 通过注解获取*.porperties文件的内容,除了xml配置外,还可以通过@value方式来获取. 使用方式必须在当前类使用@Component,xml文件内配置的是通过pakage扫 ...

  5. 【APUE】进程基础

    进程标识符:非负整数 ID为0的进程通常是是调度进程,常被称为交换进程.该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程 ID为1的进程是init进程,在自举过程结束时由内核调用 ...

  6. python绘图入门

    python绘图入门 学习了:https://zhuanlan.zhihu.com/p/34200452 API:https://matplotlib.org/api/pyplot_api.html ...

  7. Ulua_toLua_基本案例(一)

    Ulua_toLua_基本案例 在Untiy中用Lua.必需要LuaInterface.LuaInterface的介绍请看:点击打开链接 能够先光写Lua,生成.lua的纯文件.再Unity中通过,l ...

  8. Selenium系列之--01 简介【转】

    1.selenium 工具组件 1.1 selenium2,也称为selenium webdriver.webdriver原来是另一个自动化测试工具,后与selenium 合并了.webdriver直 ...

  9. [转] logback 常用配置详解(序)logback 简介

    转载文章:原文出处:http://aub.iteye.com/blog/1101222 logback 简介 Ceki Gülcü在Java日志领域世界知名.他创造了Log4J ,这个最早的Java日 ...

  10. hdu 4925 Apple Tree--2014 Multi-University Training Contest 6

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4925 Apple Tree Time Limit: 2000/1000 MS (Java/Others ...