【解题报告】 Leapin' Lizards HDU 2732 网络流

题外话

  在正式讲这个题目之前我想先说几件事
  1. 如果大家要做网络流的题目,我在网上看到一个家伙,他那里列出了一堆网络流的题目,而且还给他们分门别类,并且标注了难度,感觉挺好的,网址是[夏天的风](https://blog.csdn.net/shahdza/article/details/7779537)
  2. 这道题有个坑点!!!!

正题

  首先,当然是直接贴上[题目](http://acm.hdu.edu.cn/showproblem.php?pid=2732)的链接,题号是2732。
  然后接下来是CSDN的链接(https://blog.csdn.net/Liang_Si_FFF/article/details/84992526)。

题目大意

* 现在给你一个n*m的矩阵,每一个点表示一根柱子,柱子之间没有道路。

* 在某些柱子上面,会有蜥蜴,(每一个柱子上面最多一个蜥蜴),现在他们被困在那里了。但是每个蜥蜴都可以跳,跳的距离为d,所以只要两根柱子的距离不超过d,他们就可以跳到相邻的柱子上面。如果一个蜥蜴可以跳出矩阵外面,那么它就得救了。坑点来了!不知道是我题目没有看清楚的缘故,还是题目没有明说的缘故,这里的距离指的是曼哈顿距离。要不是我看了别人的题解,我还会一直困在样例数据呢

* 但是,每一根柱子的质量都不是很好,都有一个寿命值(整数)。每当有一个蜥蜴从这跟柱子起跳,这跟柱子的寿命值就会减一,减到0之后柱子就断了。(只有起跳的时候会减,如果有一个蜥蜴跳到这上面,是不会有事的)

* 现在问你,不能获救的蜥蜴最少是多少了?

* 坑点二:输出数据的时候,不仅要注意有和没有,而且还要注意单复数。不过还好,我一开始就注意到了。比如下面:

Case #1: 2 lizards were left behind.
Case #2: no lizard was left behind.
Case #3: 3 lizards were left behind.
Case #4: 1 lizard was left behind.

构图方法

1. 拆点,将每一个点拆成两个点,分别叫做start和end,start,然后再start之间连一条容量为寿命值的边,表示这个柱子最多只能跳几次。

2. 如果一个蜥蜴可以从柱子u跳到柱子v上面,则从u~end~连一条边到v~start~,(容量随意,只要大于u的寿命值就行)表示蜥蜴能够从这个柱子跳到另一个柱子。

3. 如果一个蜥蜴能够从柱子u跳出这个矩阵,那么就从u~end~连一条边到汇点T(同样容量随意,只要大于u的寿命值就行)

4. 如果某一个柱子u上面在初始状态下是有蜥蜴的,那么从头源点S连一条边到u~start~,容量为1,表示这个柱子上面只有一个蜥蜴(毕竟题目里面说了嘛,每根柱子上面最多只有一个蜥蜴)

5. 这个图的最大流就是能够逃出去的蜥蜴的数量。所以提前算出有多少了蜥蜴之后,减去最大流,就是不能获救的蜥蜴的个数。

AC代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. using namespace std;
  5. const int INF=;
  6. const int N=;
  7. const int M=N*N;
  8. int Head[N],Next[M],Ver[M],Edge[M],tot=;//利用前向星储存
  9. int D[N];//dinic算法需要用到的深度值
  10. int map[][];//用来存每一个柱子的寿命值
  11. int mark[][];//给每一个柱子标号
  12. int S=,T=;
  13. char temp[];//由于题目用字符串输入,所以弄一个字符数组
  14. void add(int,int,int);//连边函数
  15. bool bfs(void);//dinic算法数深度函数
  16. int dinic(int,int);//就是dinic
  17. int min(int,int);
  18. int max(int,int);
  19. int abs(int);
  20. int main()
  21. {
  22. int Case;
  23. scanf("%d",&Case);//总共要Case组数据
  24. for(int cnt=;cnt<=Case;cnt++)
  25. {
  26. memset(Head,,sizeof(Head));
  27. int n,d,m=;
  28. scanf("%d%d",&n,&d);
  29. getchar();
  30. for(int i=;i<=n;i++)
  31. {
  32. fgets(temp,,stdin);
  33. if(!m) m=strlen(temp)-;
  34. for(int j=;j<=m;j++)
  35. map[i][j]=temp[j-]-'';
  36. }
  37. int k=;
  38. for(int i=;i<=n;i++)
  39. for(int j=;j<=m;j++)
  40. mark[i][j]=k++;//这个地方就是给每一根柱子都标一个号
  41. //然后就用这个号码来标注柱子u的u_start,用u_start+T表示
  42. //u_end
  43. for(int i=;i<=n;i++)
  44. for(int j=;j<=m;j++)
  45. {
  46. if(map[i][j])
  47. {
  48. add(mark[i][j],mark[i][j]+T,map[i][j]);
  49. if(i-d<||i+d>n||j-d<||j+d>m)
  50. add(mark[i][j]+T,T,map[i][j]);
  51. int L=min(m,j+d),U=min(n,i+d);
  52. for(int I=max(,i-d);I<=U;I++)
  53. for(int J=max(,j-d);J<=L;J++)
  54. if(map[I][J]&&(I!=i||J!=j)&&(abs(I-i)+abs(J-j)<=d))
  55. add(mark[i][j]+T,mark[I][J],map[i][j]);
  56.  
  57. }
  58. }
  59. int sum=;
  60. for(int i=;i<=n;i++)
  61. {
  62. fgets(temp,,stdin);
  63. for(int j=;j<=m;j++)
  64. if(temp[j-]=='L')
  65. {
  66. add(S,mark[i][j],);
  67. sum++;
  68. }
  69. }
  70. int max_flow=;
  71. while(bfs()) max_flow+=dinic(S,INF);
  72. int left=sum-max_flow;
  73. if(left==)
  74. printf("Case #%d: no lizard was left behind.\n",cnt);
  75. else if(left==)
  76. printf("Case #%d: 1 lizard was left behind.\n",cnt);
  77. else printf("Case #%d: %d lizards were left behind.\n",cnt,left);
  78. }
  79. return ;
  80. }
  81. int dinic(int x,int flow)
  82. {
  83. if(x==T) return flow;
  84. int rest=flow;
  85. for(int p=Head[x];rest&&p;p=Next[p])
  86. {
  87. if(D[Ver[p]]==D[x]+&&Edge[p])
  88. {
  89. int k=dinic(Ver[p],min(rest,Edge[p]));
  90. if(!k) D[Ver[p]]=;
  91. Edge[p]-=k;
  92. Edge[p^]+=k;
  93. rest-=k;
  94. }
  95. }
  96. return flow-rest;
  97. }
  98. bool bfs(void)
  99. {
  100. memset(D,,sizeof(D));
  101. queue <int> q;
  102. q.push(S);
  103. D[S]=;
  104. while(!q.empty())
  105. {
  106. int x=q.front();
  107. q.pop();
  108. for(int p=Head[x];p;p=Next[p])
  109. if(!D[Ver[p]]&&Edge[p])
  110. {
  111. D[Ver[p]]=D[x]+;
  112. if(Ver[p]==T) return ;
  113. q.push(Ver[p]);
  114. }
  115. }
  116. return ;
  117. }
  118. void add(int u,int v,int c)
  119. {
  120. Next[++tot]=Head[u],Head[u]=tot,Edge[tot]=c,Ver[tot]=v;
  121. Next[++tot]=Head[v],Head[v]=tot,Edge[tot]=,Ver[tot]=u;
  122. }
  123. inline int min(int a,int b)
  124. {
  125. return a<b?a:b;
  126. }
  127. inline int max(int a,int b)
  128. {
  129. return a>b?a:b;
  130. }
  131. inline int abs(int x)
  132. {
  133. return x<?-x:x;
  134. }

【解题报告】 Leapin' Lizards HDU 2732 网络流的更多相关文章

  1. K - Leapin' Lizards HDU - 2732 网络流

    题目链接:https://vjudge.net/contest/299467#problem/K 这个题目从数据范围来看可以发现是网络流,怎么建图呢?这个其实不是特别难,主要是读题难. 这个建图就是把 ...

  2. POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)

    POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流) Description Yo ...

  3. Leapin' Lizards(hdu 2732)

    Leapin' Lizards Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. Leapin' Lizards [HDU - 2732]【网络流最大流】

    题目链接 网络流直接最大流就是了,只是要拆点小心一个点的流超出了原本的正常范围才是. #include <iostream> #include <cstdio> #includ ...

  5. K - Leapin' Lizards - HDU 2732(最大流)

    题意:在一个迷宫里面有一些蜥蜴,这个迷宫有一些柱子组成的,并且这些柱子都有一个耐久值,每当一只蜥蜴跳过耐久值就会减一,当耐久值为0的时候这个柱子就不能使用了,每个蜥蜴都有一个最大跳跃值d,现在想知道有 ...

  6. Leapin' Lizards HDU - 2732 (恶心的建图。。)

    这道题其实不难...就是建图恶心了点....emm... 题意: 多源多汇 + 拆边 青蛙跳柱子, 每根柱子都有一定的承载能力, 青蛙跳上去之后柱子的承载能力就会减一,跳到边界就能活 跳不到就over ...

  7. [ZOJ2341]Reactor Cooling解题报告|带上下界的网络流|无源汇的可行流

    Reactor Cooling The terrorist group leaded by a well known international terrorist Ben Bladen is bul ...

  8. HDU 2732 Leapin&#39; Lizards(拆点+最大流)

    HDU 2732 Leapin' Lizards 题目链接 题意:有一些蜥蜴在一个迷宫里面,有一个跳跃力表示能跳到多远的柱子,然后每根柱子最多被跳一定次数,求这些蜥蜴还有多少是不管怎样都逃不出来的. ...

  9. HDU 4303 Hourai Jeweled 解题报告

    HDU 4303 Hourai Jeweled 解题报告 评测地址: http://acm.hdu.edu.cn/showproblem.php?pid=4303 评测地址: https://xoj. ...

随机推荐

  1. 『干货』分享你最喜欢的技巧和提示(Xcode,objective-c,swift,c...等等)

    亲爱的读者们,你们好 !年底将近,分享从过去一年你最喜欢的技巧和建议作为礼物送给新手们.提交你的最喜欢的迅速或objc琐事,实用的提示,意外的发现,实用的解决方法,没用的迷恋,或不论什么其它你认为今年 ...

  2. POJ-3268-最短路(dijkstra算法)

    Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12494   Accepted: 5568 ...

  3. javascript 和 CoffeeScript 里的类

    javascript不是面向对象的语言,它用函数来模拟类和继承. javascript里,提供一个类并不难: var Person,l4, z3; Person = function(name) { ...

  4. 360p以上

    请选择200MB以内,360p以上,时长3秒到300秒的文件.(支持格式:mp4.3gp.avi.mov.m4v.mkv文件)

  5. 插入排序(1)——直接插入排序(insert sort)

    假设有一组无序序列 R0, R1, ... , RN-1. (1) 我们先将这个序列中下标为 0 的元素视为元素个数为 1 的有序序列. (2) 然后,我们要依次把 R1, R2, ... , RN- ...

  6. JSP-Runoob:JSP 服务器响应

    ylbtech-JSP-Runoob:JSP 服务器响应 1.返回顶部 1. JSP 服务器响应 Response响应对象主要将JSP容器处理后的结果传回到客户端.可以通过response变量设置HT ...

  7. Scala快速统计文件中特定单词,字符的个数

    val fileContent=Source.fromFile("/home/soyo/桌面/ss5.txt").getLines.mkString(",") ...

  8. 阿拉伯数字1与英语字母l造成的代码bug

    <img src="./images/demo3/1a.png" /> <img src="./images/demo3/la.png" /& ...

  9. Spark 概念学习系列之Spark基本概念和模型(十八)

    打好基础,别小瞧它! spark的运行模式多种多样,在单机上既可以本地模式运行,也可以伪分布模式运行.而当以分布式的方式在集群中运行时.底层的资源调度可以使用Mesos或者Yarn,也可使用spark ...

  10. asp.net mvc 最简单身份验证 [Authorize]通过的标准

    [Authorize] public ContentResult Index2() { return Content("验证通过了"); } 经常能够看到某个Controler下的 ...