【bzoj1066】[SCOI2007]蜥蜴

Description

在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。

Input

输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

Output

输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

Sample Input

5 8 2
00000000
02000000
00321100
02000000
00000000
……..
……..
..LLLL..
……..
……..

Sample Output

1

HINT

100%的数据满足:1<=r, c<=20, 1<=d<=3

代码

对于每根石柱,采取一分为二的想法,即把一个点分为两个点(可抽象为石柱底部到顶部),其连线容量限制为石柱高度。

超级源与所有有蜥蜴的点相连,容量为1。

超级汇与地图内所有能跳出的点的底端相连,容量为INF。

对于地图内任意两个石柱,如果间距小于d,就将其中一根石柱的底部与另一根石柱的顶部相连,其连线容量为INF。

构图完成,剩下就是跑一遍最大流,然后用蜥蜴数量减去最大流就是最终结果。

  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <ctime>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <set>
  8. #include <vector>
  9. #include <queue>
  10. #include <typeinfo>
  11. #include <map>
  12. #include <stack>
  13. typedef long long ll;
  14. using namespace std;
  15. inline ll read()
  16. {
  17. ll x=,f=;
  18. char ch=getchar();
  19. while(ch<''||ch>'')
  20. {
  21. if(ch=='-')f=-;
  22. ch=getchar();
  23. }
  24. while(ch>=''&&ch<='')
  25. {
  26. x=x*+ch-'';
  27. ch=getchar();
  28. }
  29. return x*f;
  30. }
  31. //***************************
  32. namespace NetFlow
  33. {
  34. const int MAXN=,MAXM=,inf=1e9;
  35. struct Edge
  36. {
  37. int v,c,f,nx;
  38. Edge() {}
  39. Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
  40. } E[MAXM];
  41. int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz;
  42. void init(int _n)
  43. {
  44. N=_n,sz=;
  45. memset(G,-,sizeof(G[])*N);
  46. }
  47. void link(int u,int v,int c)
  48. {
  49. E[sz]=Edge(v,c,,G[u]);
  50. G[u]=sz++;
  51. E[sz]=Edge(u,,,G[v]);
  52. G[v]=sz++;
  53. }
  54. int ISAP(int S,int T)
  55. {
  56. //S -> T
  57. int maxflow=,aug=inf,flag=false,u,v;
  58. for (int i=; i<N; ++i)cur[i]=G[i],gap[i]=dis[i]=;
  59. for (gap[S]=N,u=pre[S]=S; dis[S]<N; flag=false)
  60. {
  61. for (int &it=cur[u]; ~it; it=E[it].nx)
  62. {
  63. if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+)
  64. {
  65. if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f;
  66. pre[v]=u,u=v;
  67. flag=true;
  68. if (u==T)
  69. {
  70. for (maxflow+=aug; u!=S;)
  71. {
  72. E[cur[u=pre[u]]].f+=aug;
  73. E[cur[u]^].f-=aug;
  74. }
  75. aug=inf;
  76. }
  77. break;
  78. }
  79. }
  80. if (flag) continue;
  81. int mx=N;
  82. for (int it=G[u]; ~it; it=E[it].nx)
  83. {
  84. if (E[it].c>E[it].f&&dis[E[it].v]<mx)
  85. {
  86. mx=dis[E[it].v];
  87. cur[u]=it;
  88. }
  89. }
  90. if ((--gap[dis[u]])==) break;
  91. ++gap[dis[u]=mx+];
  92. u=pre[u];
  93. }
  94. return maxflow;
  95. }
  96. bool bfs(int S,int T)
  97. {
  98. static int Q[MAXN];
  99. memset(dis,-,sizeof(dis[])*N);
  100. dis[S]=;
  101. Q[]=S;
  102. for (int h=,t=,u,v,it; h<t; ++h)
  103. {
  104. for (u=Q[h],it=G[u]; ~it; it=E[it].nx)
  105. {
  106. if (dis[v=E[it].v]==-&&E[it].c>E[it].f)
  107. {
  108. dis[v]=dis[u]+;
  109. Q[t++]=v;
  110. }
  111. }
  112. }
  113. return dis[T]!=-;
  114. }
  115. int dfs(int u,int T,int low)
  116. {
  117. if (u==T) return low;
  118. int ret=,tmp,v;
  119. for (int &it=cur[u]; ~it&&ret<low; it=E[it].nx)
  120. {
  121. if (dis[v=E[it].v]==dis[u]+&&E[it].c>E[it].f)
  122. {
  123. if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
  124. {
  125. ret+=tmp;
  126. E[it].f+=tmp;
  127. E[it^].f-=tmp;
  128. }
  129. }
  130. }
  131. if (!ret) dis[u]=-;
  132. return ret;
  133. }
  134. int dinic(int S,int T)
  135. {
  136. int maxflow=,tmp;
  137. while (bfs(S,T))
  138. {
  139. memcpy(cur,G,sizeof(G[])*N);
  140. while (tmp=dfs(S,T,inf)) maxflow+=tmp;
  141. }
  142. return maxflow;
  143. }
  144. }
  145. using namespace NetFlow;
  146. double dist(int a,int b,int x,int y)
  147. {
  148. return sqrt((b-y)*(b-y)+(a-x)*(a-x));
  149. }
  150. int main()
  151. {
  152. int n,m,d;
  153. char mp[][],mp2[][];
  154. cin>>n>>m>>d;
  155. init();
  156. for(int i=; i<=n; i++)
  157. {
  158. scanf("%s",mp[i]+);
  159. }
  160. for(int i=; i<=n; i++)
  161. {
  162. scanf("%s",mp2[i]+);
  163. }
  164. for(int i=; i<=n; i++)
  165. {
  166. for(int j=; j<=m; j++)
  167. {
  168. if((mp[i][j]-'')>)
  169. {
  170. for(int h=i-d; h<=i+d; h++)
  171. {
  172. for(int k=j-d; k<=j+d; k++)
  173. {
  174. if(h==i&&j==k)continue;
  175. if(h<||k<||h>n+||k>m+)
  176. continue;
  177. double dd=d*1.0;
  178. if(dist(i,j,h,k)>dd)continue;
  179. if(h==||k==||h==n+||k==m+)
  180. link((i-)*m+j+,,inf);
  181. else link((i-)*m+j+,(h-)*m+k,inf);
  182. }
  183. }
  184. link((i-)*m+j,(i-)*m+j+,mp[i][j]-'');
  185. }
  186.  
  187. }
  188. }
  189. int sum=;
  190. for(int i=; i<=n; i++)
  191. {
  192. for(int j=; j<=m; j++)
  193. {
  194. if(mp2[i][j]=='L')
  195. {
  196. sum++;
  197. link(,(i-)*m+j,);
  198. }
  199. }
  200. }
  201. cout<<sum-dinic(,)<<endl;
  202. return ;
  203. }

补:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #pragma comment(linker, "/STACK:102400000,102400000")
  4. #define ls i<<1
  5. #define rs ls | 1
  6. #define mid ((ll+rr)>>1)
  7. #define pii pair<int,int>
  8. #define MP make_pair
  9. typedef long long LL;
  10. const long long INF = 1e18+1LL;
  11. const double Pi = acos(-1.0);
  12. const int N = 1e3+, M = 1e3+, mod = 1e9+, inf = 2e9;
  13.  
  14. char s[];
  15. int head[N],S,T,r,c,d,t=,h[N],height[][],q[N],ans;
  16. struct edge{int to,next,v;}e[N*N];
  17. void adds(int u,int v,int w) {e[t].next=head[u];e[t].to=v;e[t].v=w;head[u]=t++;}
  18. void add(int u,int v,int w) {adds(u,v,w);adds(v,u,);}
  19.  
  20. bool bfs() {
  21. memset(h,-,sizeof(h));
  22. int l = , r = ,now;
  23. q[l] = S;
  24. h[S] = ;
  25. while(l!=r) {
  26. now=q[l++];if(l == ) l=;
  27. for(int i=head[now];i;i=e[i].next) {
  28. if(e[i].v&&h[e[i].to]==-) {
  29. h[e[i].to] = h[now] + ;
  30. q[r++]=e[i].to;
  31. if(r == ) r = ;
  32. }
  33. }
  34. }
  35. if(h[T] == -) return ;
  36. return ;
  37. }
  38. int dfs(int x,int f) {
  39. if(x == T) return f;
  40. int used=,w;
  41. for(int i=head[x];i;i=e[i].next) {
  42. if(e[i].v&&h[e[i].to] == h[x]+) {
  43. w = dfs(e[i].to,min(f-used,e[i].v));
  44. used+=w;e[i].v-=w;e[i^].v+=w;
  45. if(used == f) return f;
  46. }
  47. }
  48. return used;
  49. }
  50. void dinic() {while(bfs()) ans+=dfs(S,inf);}
  51.  
  52. double dis(int i,int j,int k,int h) {return sqrt(1.0*(i-k)*(i-k) + 1.0*(j-h)*(j-h));}
  53. int main() {
  54. scanf("%d%d%d",&r,&c,&d);
  55. S=*r*c,T=S+;
  56. for(int i = ; i <= r; ++i)
  57. {
  58. scanf("%s",s+);
  59. for(int j = ; j <= c; ++j)
  60. {
  61. height[i][j] = s[j]-'';
  62. add((i-)*c+j,(i-)*c+j+r*c,height[i][j]);
  63. if(i-d<=||j-d<=||i+d>r||j+d>c)
  64. {
  65. add((i-)*c+j+r*c,T,inf);
  66. }
  67. }
  68. }
  69. int sum = ;
  70. for(int i = ; i <= r; ++i)
  71. {
  72. scanf("%s",s+);
  73. for(int j = ; j <= c; ++j) {
  74. if(s[j] == 'L')
  75. {
  76. sum++;
  77. add(S,(i-)*c+j,);
  78. }
  79. for(int k = ; k <= r; ++k)
  80. for(int h = ; h <= c; ++h) {
  81. if((k!=i||j!=h) && dis(i,j,k,h) <= 1.0*d)
  82. {
  83. add((i-)*c+j+r*c,(k-)*c+h,inf);
  84. }
  85. }
  86. }
  87. }
  88. dinic();
  89. printf("%d\n",sum-ans);
  90. //cout<<sum-ans<<endl;
  91. return ;
  92. }

dinic

【bzoj1066】[SCOI2007]蜥蜴 网络最大流的更多相关文章

  1. bzoj1066: [SCOI2007]蜥蜴(最大流)

    1066: [SCOI2007]蜥蜴 题目:传送门 题解: 哇QTT大佬一眼秒算法...ORT 其实很容易就可以看出来是一道最大流 因为有边的使用限制,那么就可以直接当成是流量来处理嘛 因为是对点进行 ...

  2. BZOJ1066 [SCOI2007]蜥蜴 网络流 最大流 SAP

    由于本题和HDU2732几乎相同,所以读者可以看-> HDU2732题解传送门: http://www.cnblogs.com/zhouzhendong/p/8362002.html

  3. BZOJ1066 SCOI2007 蜥蜴 【网络流-最大流】

    BZOJ1066 SCOI2007 蜥蜴 Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离 ...

  4. 【bzoj1066】: [SCOI2007]蜥蜴 图论-最大流

    [bzoj1066]: [SCOI2007]蜥蜴 把石柱拆点,流量为高度 然后S与蜥蜴连流量1的边 互相能跳到的石柱连inf的边 石柱能到边界外的和T连inf的边 然后跑dinic就好了 /* htt ...

  5. P2472 [SCOI2007]蜥蜴(最大流)

    P2472 [SCOI2007]蜥蜴 自己第一道独立做题且一遍AC的网络流题纪念... 看到这道题我就想到网络流建图的方式了... 首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离, ...

  6. bzoj千题计划135:bzoj1066: [SCOI2007]蜥蜴

    http://www.lydsy.com/JudgeOnline/problem.php?id=1066 每个柱子拆成两个点 i<<1,i<<1|1,之间连流量为高度的边 如果 ...

  7. 【BZOJ】1066: [SCOI2007]蜥蜴(最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1066 本题想一想应该懂了的. 我们想啊,,每个点都有限制,每个点都可以跳到另一个有限制的点,每个有蜥 ...

  8. BZOJ1066 [SCOI2007]蜥蜴

    首先...这是道(很水的)网络流 我们发现"每个时刻不能有两个蜥蜴在同一个柱子上"这个条件是没有用的因为可以让外面的先跳,再让里面的往外跳 但是还有柱子高度的限制,于是把柱子拆点为 ...

  9. [BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】

    题目链接:BZOJ - 1066 题目分析 题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制.我们把每个石柱看作一个点,每个点拆成 i1, i2,从 ...

随机推荐

  1. spark1.6配置sparksql 的元数据存储到postgresql中

    1:首先配置hive-site.xml <configuration> <property> <name>javax.jdo.option.ConnectionUR ...

  2. 新浪微博客户端(9)-实现版本新特性的ViewPager

    "DJNewFeatureViewController.m" #import "DJNewFeatureViewController.h" #define NE ...

  3. thinkphp 3.23 第三方登录sdk集成包

    本集成包在官方包上扩展了支付宝登录和微信,支持最新的3.23版本 config    /* URL配置 */     'URL_CASE_INSENSITIVE' => true, //默认fa ...

  4. Entity Framework简介

    前言 很久很久之前就想来好好的学习一下EF,一直也是各种理由导致一直也没有好好的开始,现在下定决心了,不管怎样一定要把这先走一遍,并且把自己学到的相关EF的知识进行记录,以备后用,也望广大博友们一起来 ...

  5. XSS跨站脚本攻击实例讲解,新浪微博XSS漏洞过程分析

    2011年6月28日晚,新浪微博遭遇到XSS蠕虫攻击侵袭,在不到一个小时的时间,超过3万微博用户受到该XSS蠕虫的攻击.此事件给严重依赖社交网络的网友们敲响了警钟.在此之前,国内多家著名的SNS网站和 ...

  6. Windbg对过滤驱动DriverEntry函数下断点技巧

    方法1: 1> 先用DeviceTree.exe查看指定的过滤驱动的Load Address(加载地址) 2> 再用LordPE.EXE查看指定过滤驱动文件的入口点地址 3> 计算过 ...

  7. [Effective JavaScript 笔记]第54条:将undefined看做“没有值”

    undefined值很特殊,每当js无法提供具体的值时,就会产生undefined. undefined值场景 未赋值的变量的初始值即为undefined. var x; x;//undefined ...

  8. FATAL: ActionView::Template::Error (application.css isn't precompiled):

    iwangzheng.com tty:[0] jobs:[0] cwd:[/opt/logs/m]13:02 [root@a02.cmsapi$ tail thin\ server\ \(0.0.0. ...

  9. qsort用法总结

    一.对int类型数组排序 ]; int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(nu ...

  10. tornado--之cookie自定义(还有session)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhAAAAHzCAIAAAD+WrNvAAAgAElEQVR4nOy993cTV7/vf/6qu865ob