Problem Jump (HDU4862)

题目大意

  给定一个n*m的矩形(n,m≤10),每个矩形中有一个0~9的数字。

  一共可以进行k次游戏,每次游戏可以任意选取一个没有经过的格子为起点,并且跳任意多步,每步可以向右方和下方跳。每次跳需要消耗两点间的曼哈顿距离减一的能量,若每次跳的起点和终点的数字相同,可以获得该数字的能量。(能量可以为负)

  询问k次或更少次游戏后是否可以经过所有的格子,若可以求出最大的剩余能量。

解题分析

  带权值的最小K路径覆盖。

(最小路径覆盖数=总节点数-最大匹配数)

  将n*m个点,每个点拆成两个,X,Y。

  由S向X连容量为1费用为0的边,Y向T连容量为1费用为0的边,X向可到达的Y连容量为1费用为所消耗能量(加上所得)。

  这样直接跑可求出最大匹配数。所有未流满的Y点数量即为最小路径覆盖数。

  考虑如何实现K路径覆盖。

  新建一个点Q,由S向Q连容量为k费用为0的边,有Q向Y连容量为1费用为0的边。即表示可以新增的起点数为k。

  这样跑一遍最小费用最大流,若不是满流则说明无解。

参考程序

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. #define V 2008
  8. #define E 1000008
  9. #define INF 200000000
  10. int n,m,k,S,T,Que,num;
  11. int a[V][V],mark[V][V];
  12.  
  13. int pd[V],dis[V],pre[V];
  14. struct line{
  15. int u,v,c,w,nt;
  16. }eg[E];
  17. int lt[V],sum;
  18.  
  19. void adt(int u,int v,int c,int w) {
  20. eg[++sum].u=u; eg[sum].v=v; eg[sum].c=c;
  21. eg[sum].w=w; eg[sum].nt=lt[u]; lt[u]=sum;
  22. }
  23.  
  24. void add(int u,int v,int c,int w) {
  25. adt(u,v,c,w); adt(v,u,,-w);
  26. //printf("%d %d %d %d\n",u,v,c,w);
  27. }
  28.  
  29. void init(){
  30.  
  31. sum=; num=;
  32. memset(lt,,sizeof(lt));
  33.  
  34. char s[V];
  35. scanf("%d %d %d",&n,&m,&k);
  36. for (int i=;i<=n;i++){
  37. scanf("%s",s+);
  38. for (int j=;j<=m;j++)
  39. {
  40. a[i][j]=s[j]-'';
  41. mark[i][j]=++num;
  42. }
  43. }
  44.  
  45. S=; T=num*+;
  46. add(S,T-,k,);
  47. for (int i=;i<=n;i++)
  48. for (int j=;j<=m;j++)
  49. {
  50. add(S,mark[i][j],,);
  51. add(mark[i][j]+num,T,,);
  52. add(T-,mark[i][j]+num,,);
  53. }
  54. for (int i=;i<=n;i++)
  55. for (int j=;j<=m;j++)
  56. for (int k=;k<=n;k++)
  57. for (int l=;l<=m;l++)
  58. if (i==k && l>j || j==l && k>i)
  59. {
  60. int x=abs(i-k)+abs(j-l)-;
  61. if (a[i][j]==a[k][l]) x-=a[i][j];
  62. add(mark[i][j],mark[k][l]+num,,x);
  63. }
  64. n=T;
  65. }
  66.  
  67. bool spfa() {
  68. queue <int> Q;
  69. for (int i=;i<=n;i++) {
  70. dis[i]=INF;
  71. pd[i]=;
  72. pre[i]=-;
  73. }
  74. dis[S]=; pd[S]=; Q.push(S);
  75. while (!Q.empty()) {
  76. int u = Q.front();
  77. for (int i=lt[u];i;i=eg[i].nt)
  78. if (eg[i].c>) {
  79. int v=eg[i].v;
  80. if (dis[u]+eg[i].w<dis[v]) {
  81. dis[v]=dis[u]+eg[i].w;
  82. pre[v]=i;
  83. if (!pd[v]) {
  84. Q.push(v);
  85. pd[v]=;
  86. }
  87. }
  88. }
  89. pd[u]=;
  90. Q.pop();
  91. }
  92. return dis[T]!=INF;
  93. }
  94.  
  95. void minCmaxF(){
  96. int minC=,maxF=,flow;
  97. while (spfa()) {
  98. flow=INF;
  99. for (int i=pre[T];~i;i=pre[eg[i].u])
  100. flow=min(flow,eg[i].c);
  101. for (int i=pre[T];~i;i=pre[eg[i].u]) {
  102. eg[i].c-=flow;
  103. eg[i^].c+=flow;
  104. }
  105. maxF+=flow;
  106. minC+=flow*dis[T];
  107. }
  108. if (maxF==num) printf("%d\n",-minC); else printf("-1\n");
  109.  
  110. }
  111.  
  112. int main(){
  113. scanf("%d",&Que);
  114. for (int tt=;tt<=Que;tt++){
  115. init();
  116. printf("Case %d : ",tt );
  117. minCmaxF();
  118. }
  119. }

HDU 4862(费用流)的更多相关文章

  1. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  2. hdu 5045 费用流

    滚动建图,最大费用流(每次仅仅有就10个点的二分图).复杂度,m/n*(n^2)(n<=10),今年网络赛唯一网络流题,被队友状压DP秒了....难道网络流要逐渐退出历史舞台???.... #i ...

  3. HDU 3376 费用流 Matrix Again

    题意: 给出一个n × n的矩阵,每个格子中有一个数字代表权值,找出从左上角出发到右下角的两条不相交的路径(起点和终点除外),使得两条路径权值之和最大. 分析: 如果n比较小的话是可以DP的,但是现在 ...

  4. hdu 2686 费用流 / 双线程DP

    题意:给一个方阵,求从左上角出到右下角(并返回到起点),经过每个点一次不重复,求最大获益(走到某处获得改点数值),下来时每次只能向右或向下,反之向上或向左. 俩种解法: 1  费用流法:思路转化:从左 ...

  5. hdu 4406 费用流

    这题问题就是当前时刻究竟选择哪门课程,易知选择是和分数有关的,而且是一个变化的权值,所以能够用拆点的方式,把从基础分到100分都拆成点.但若这样拆点的话,跑费用流时就必须保证顺序.这样就麻烦了..观察 ...

  6. hdu 1853 (费用流 拆点)

    // 给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小. 思路:原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从 u' 引相同性质的边到汇点 ...

  7. HDU 3667 费用流 拆边 Transportation

    题意: 有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市. 每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai 而且每条路最多运送Ci个货物,求最小费用. 分析: ...

  8. HDU 3667 费用流(拆边)

    题意:有n个城市(1~n),m条有向边:有k件货物要从1运到n,每条边最多能运c件货物,每条边有一个危险系数ai,经过这条路的费用需要ai*x2(x为货物的数量),问所有货物安全到达的费用. 思路:c ...

  9. HDU 5644 (费用流)

    Problem King's Pilots (HDU 5644) 题目大意 举办一次持续n天的飞行表演,第i天需要Pi个飞行员.共有m种休假计划,每个飞行员表演1次后,需要休假Si天,并提供Ti报酬来 ...

  10. HDU - 4780费用流

    题意:M台机器要生产n个糖果,糖果i的生产区间在(si, ti),花费是k(pi-si),pi是实际开始生产的时间机器,j从初始化到生产糖果i所需的时间Cij,花费是Dij,任意机器从生产糖果i到生产 ...

随机推荐

  1. 读书笔记2:HTTP协议

    HTTP是什么 HTTP定义 HTTP( Hypertext Transfer Protocol, 超文本传输协议) 是在万维网上进行通信时所使用 的协议方案. HTTP的地位 了解HTTP协议的地位 ...

  2. go——beego的数据库增删改查

    一直都不理解使用go语言的时候,为什么还要自己去装beego,以为使用go便可以解决所有的问题,结果在朋友的点拨下,才意识到: go与beego的关系就好比是nodejs与thinkjs的关系,因此也 ...

  3. vim 代码

    vim函数跳转                     时间:2014-05-07 14:02:12                         阅读:40                     ...

  4. CentOS 下的MySQL配置

    先贴出代码(/etc/my.cnf)如下: #The following options will be passed to all MySQL clients [client] #password ...

  5. LAMP整理

    LAMP第一部分 查看编译了哪些软件:是编译时自动生成的 Cat /usr/local/apache2/build/config.nice 网站根目录存放处: /usr/local/apache2/h ...

  6. ASP.NET备份还原数据库

    核心技术:using System.Data.SqlClient;using System.IO;string SqlStr1 = "Server=(local);DataBase=mast ...

  7. hdu 4609 3-idiots

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 FFT  不会 找了个模板 代码: #include <iostream> #include ...

  8. C++定义构造函数必须使用初始化列表的场合

    明其理,而知其然也. 先给理论.1. 初始化 != 赋值. a.初始化代表为变量分配内存. 变量在其定义处被编译器初始化(编译时). 在函数中, 函数参数初始化发生在函数调用时(运行时). b.赋值代 ...

  9. NOIP2010解题报告

    今天状态不错..1个小时AC了前3题,第四题第一次也拿到了80%的分数,后来换了算法才拿到全部分数.. 第一题: 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 这个翻译软件的原 ...

  10. wp8.1 C#技巧: 计时器

    public MainPage() { this.InitializeComponent(); this.timer = new DispatcherTimer();//新建委托时间实例 timer. ...