先不考虑只有一个显得有些特殊的天兵。

  可以发现超能力的作用实质上是使兵更换职业。每一个兵到达某个位置最少需要更换职业的次数是彼此独立的,因为如果需要某两人互换职业可以使他们各自以当前职业到达需要到的地方,不会造成其中一个次数增加。

  于是预处理出每个兵到达每个位置的最少代价。之后二分答案,把每个兵向可以到达的目标位置连边。跑最大流就可以知道是否可行。

  最后考虑天兵。天兵可以任意游走,并且与天兵换职业的兵可以直接到达目的地。那么在最大流的结果上加上二分出的答案即可,因为每次使用超能力都可以送走一个兵。

  1A爽爆。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<queue>
  8. using namespace std;
  9. int read()
  10. {
  11. int x=,f=;char c=getchar();
  12. while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
  13. while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
  14. return x*f;
  15. }
  16. #define N 110
  17. int n,m,k,l,dis[N][N][N],a[N][N],w[N][N],ans;
  18. struct pos{int x,y;}u[N],v[N];
  19. namespace shortestpath
  20. {
  21. int d[N*N<<],p[N*N<<],t=;
  22. int wx[]={,,-,},wy[]={,,,-};
  23. bool flag[N*N<<];
  24. struct data{int to,nxt,len;}edge[N*N<<];
  25. int trans(int x,int y,int op){return op*n*m+(x-)*m+y;}
  26. void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
  27. struct data2
  28. {
  29. int x,d;
  30. bool operator <(const data2&a) const
  31. {
  32. return d>a.d;
  33. }
  34. };
  35. priority_queue<data2> q;
  36. void make()
  37. {
  38. for (int i=;i<=n;i++)
  39. for (int j=;j<=m;j++)
  40. {
  41. for (int k=;k<;k++)
  42. if (i+wx[k]>&&i+wx[k]<=n&&j+wy[k]>&&j+wy[k]<=m)
  43. if (a[i][j]<a[i+wx[k]][j+wy[k]])
  44. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
  45. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
  46. else if (a[i][j]>a[i+wx[k]][j+wy[k]])
  47. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
  48. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
  49. else
  50. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),),
  51. addedge(trans(i,j,),trans(i+wx[k],j+wy[k],),);
  52. }
  53. }
  54. void dijkstra(int start)
  55. {
  56. memset(d,,sizeof(d));d[trans(u[start].x,u[start].y,start>k)]=;
  57. memset(flag,,sizeof(flag));
  58. while (!q.empty()) q.pop();
  59. q.push((data2){trans(u[start].x,u[start].y,start>k),});
  60. for (int i=;i<=(n*m<<);i++)
  61. {
  62. while (!q.empty()&&flag[q.top().x]) q.pop();
  63. if (q.empty()) break;
  64. data2 v=q.top();q.pop();
  65. flag[v.x]=;
  66. for (int j=p[v.x];j;j=edge[j].nxt)
  67. if (v.d+edge[j].len<d[edge[j].to])
  68. {
  69. d[edge[j].to]=v.d+edge[j].len;
  70. q.push((data2){edge[j].to,d[edge[j].to]});
  71. }
  72. }
  73. for (int i=;i<=n;i++)
  74. for (int j=;j<=m;j++)
  75. dis[start][i][j]=min(d[trans(i,j,)],d[trans(i,j,)]);
  76. }
  77. }
  78. namespace maxflow
  79. {
  80. const int S=,T=;
  81. int ans,p[N<<],d[N<<],q[N<<],cur[N<<],t;
  82. struct data{int to,nxt,cap,flow;}edge[N*N<<];
  83. void addedge(int x,int y,int z)
  84. {
  85. t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
  86. t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
  87. }
  88. bool bfs()
  89. {
  90. memset(d,,sizeof(d));d[S]=;
  91. int head=,tail=;q[]=S;
  92. do
  93. {
  94. int x=q[++head];
  95. for (int i=p[x];~i;i=edge[i].nxt)
  96. if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
  97. {
  98. d[edge[i].to]=d[x]+;
  99. q[++tail]=edge[i].to;
  100. }
  101. }while (head<tail);
  102. return ~d[T];
  103. }
  104. int work(int k,int f)
  105. {
  106. if (k==T) return f;
  107. int used=;
  108. for (int i=cur[k];~i;i=edge[i].nxt)
  109. if (d[k]+==d[edge[i].to])
  110. {
  111. int w=work(edge[i].to,min(edge[i].cap-edge[i].flow,f-used));
  112. edge[i].flow+=w,edge[i^].flow-=w;
  113. if (edge[i].flow<edge[i].cap) cur[k]=i;
  114. used+=w;if (used==f) return f;
  115. }
  116. if (used==) d[k]=-;
  117. return used;
  118. }
  119. void make(int lim)
  120. {
  121. t=-;memset(p,,sizeof(p));
  122. for (int i=;i<=(k<<);i++) addedge(S,i,);
  123. for (int i=;i<=l;i++) addedge((k<<)+i,T,w[v[i].x][v[i].y]);
  124. for (int i=;i<=(k<<);i++)
  125. for (int j=;j<=l;j++)
  126. if (dis[i][v[j].x][v[j].y]<=lim) addedge(i,(k<<)+j,);
  127. }
  128. int dinic(int lim)
  129. {
  130. make(lim);
  131. ans=;
  132. while (bfs())
  133. {
  134. memcpy(cur,p,sizeof(p));
  135. ans+=work(S,N);
  136. }
  137. return ans;
  138. }
  139. }
  140. int main()
  141. {
  142. #ifndef ONLINE_JUDGE
  143. freopen("bzoj2547.in","r",stdin);
  144. freopen("bzoj2547.out","w",stdout);
  145. const char LL[]="%I64d\n";
  146. #else
  147. const char LL[]="%lld\n";
  148. #endif
  149. n=read(),m=read(),k=read(),l=read();
  150. for (int i=;i<=(k<<|);i++) u[i].x=read(),u[i].y=read();
  151. for (int i=;i<=l;i++) v[i].x=read(),v[i].y=read(),w[v[i].x][v[i].y]=read();
  152. for (int i=;i<=n;i++)
  153. for (int j=;j<=m;j++)
  154. a[i][j]=read();
  155. shortestpath::make();
  156. for (int i=;i<=(k<<);i++) shortestpath::dijkstra(i);
  157. int l=,r=k<<,ans;
  158. while (l<=r)
  159. {
  160. int mid=l+r>>;
  161. if (maxflow::dinic(mid)+mid>=(k<<)) ans=mid,r=mid-;
  162. else l=mid+;
  163. }
  164. cout<<ans;
  165. return ;
  166. }

BZOJ2547 CTSC2002玩具兵(最短路径+二分答案+最大流)的更多相关文章

  1. bzoj2547: [Ctsc2002]玩具兵

    划了一天水,其实我还是有点愧疚的. 传送门 其实是水题,然而我真是太蠢了... 首先不考虑天兵,其他兵要到一个点去一定是通过它-另一种兵-它……这样多次交换的,并且交换对象是无所谓的,和它换的兵最终会 ...

  2. [Bzoj 2547] [Ctsc2002] 玩具兵

    2547: [Ctsc2002]玩具兵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 317  Solved: 152[Submit][Status] ...

  3. BZOJ 2547: [Ctsc2002]玩具兵(二分答案+二分图匹配)

    传送门 解题思路 可以发现天兵不用管,答案的一个上界是\(2*k\),就是天兵一个个换.刚开始写了个拆\(6\)点的网络流,调了半天发现自己假了..说说正解,首先可以发现交换士兵其实就是种类的交换,那 ...

  4. BZOJ 1570: [JSOI2008]Blue Mary的旅行( 二分答案 + 最大流 )

    二分答案, 然后对于答案m, 把地点分成m层, 对于边(u, v), 第x层的u -> 第x+1层的v 连边. 然后第x层的u -> 第x+1层的u连边(+oo), S->第一层的1 ...

  5. BZOJ 1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛( floyd + 二分答案 + 最大流 )

    一道水题WA了这么多次真是.... 统考终于完 ( 挂 ) 了...可以好好写题了... 先floyd跑出各个点的最短路 , 然后二分答案 m , 再建图. 每个 farm 拆成一个 cow 点和一个 ...

  6. BZOJ 1305 CQOI2009 dance跳舞 二分答案+最大流

    题目大意:给定n个男生和n个女生,一些互相喜欢而一些不.举行几次舞会,每次舞会要配成n对.不能有同样的组合出现.每一个人仅仅能与不喜欢的人跳k次舞,求最多举行几次舞会 将一个人拆成两个点.点1向点2连 ...

  7. HDU3081(KB11-N 二分答案+最大流)

    Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. Gym - 101908G 二分答案+最大流

    After the end of the truck drivers' strike, you and the rest of Nlogônia logistics specialists now h ...

  9. 紫书 习题 11-10 UVa 12264 (二分答案+最大流)

    书上写的是UVa 12011, 实际上是 12264 参考了https://blog.csdn.net/xl2015190026/article/details/51902823 这道题就是求出一种最 ...

随机推荐

  1. Java java.text.ParseException: Unparseable date

    用java将字符串转换成Date类型是,会出现java.text.ParseException: Unparseable date异常. 例如下面的这段代码就会出现上面的异常: public bool ...

  2. 用python2.7.9 写个小程序搜索某个目录下行有某关键字

    # -*- coding: utf-8 -*-import sysreload(sys)sys.setdefaultencoding("utf-8")import os def p ...

  3. 【小程序】<image>图片实现宽度100%时,高度自适应

    *.wxss样式设置 .img{ width:100% } *.wxml给<image>标签添加属性  mode="widthFix" <image class= ...

  4. HUE的安装

    HUE: Hadoop User Experience 官网地址:http://gethue.com/ Hue官网无法下载,超时. 使用CDH版本安装. 下载地址: http://archive.cl ...

  5. 20155206 Exp2 后门原理与实践

    20155206 Exp2 后门原理与实践 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机IP 然后使用ncat.exe程序,ncat. ...

  6. Spring集成Swagger,Java自动生成Api文档

    博主很懒... Swagger官网:http://swagger.io GitHub地址:https://github.com/swagger-api 官方注解文档:http://docs.swagg ...

  7. vue.js 2.0 官方文档学习笔记 —— 01. vue 介绍

    这是我的vue.js 2.0的学习笔记,采取了将官方文档中的代码集中到一个文件的形式.目的是保存下来,方便自己查阅. !官方文档:https://cn.vuejs.org/v2/guide/ 01. ...

  8. 【第八课】php-fpm.conf配置文件解析

    在discuz论坛的nginx配置文件当中,我们可以看到有一段php解析的配置,如下: location ~ \.php$ { try_files $uri = 404; fastcgi_pass 1 ...

  9. CodeForces-1155D Beautiful Array

    Description You are given an array \(a\) consisting of \(n\) integers. Beauty of array is the maximu ...

  10. mysql安装版多次安装导致安装失败的解决方法(windows)(直接使用免安装方法)

    https://www.cnblogs.com/feilongblog/p/mysql_install_init.html 测试成功 要点:mysqld install MySQL --default ...