题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍

官方题解——一张图教你做人...

三个棋子将网格边界分成三段,添加障碍后网格中一定存在一个点使得它可以到这三段(只走障碍的路径,八连通)

所以找出这三段后分别以它们为起点跑最短路即可,经过障碍权值为$0$,经过空地权值为$1$

  1. #include<stdio.h>
  2. #include<queue>
  3. #include<string.h>
  4. #include<vector>
  5. #include<string>
  6. using namespace std;
  7. int h[410],nex[7010],to[7010],v[7010],M;
  8. void add(int a,int b,int c){
  9. M++;
  10. to[M]=b;
  11. v[M]=c;
  12. nex[M]=h[a];
  13. h[a]=M;
  14. }
  15. int dis[410];
  16. struct pr{
  17. int x,d;
  18. pr(int u=0){x=u;d=dis[u];}
  19. }t;
  20. bool operator<(pr a,pr b){return a.d>b.d;}
  21. priority_queue<pr>q;
  22. void dijk(int x){
  23. int i;
  24. memset(dis,63,sizeof(dis));
  25. dis[x]=0;
  26. q.push(x);
  27. while(!q.empty()){
  28. t=q.top();
  29. q.pop();
  30. x=t.x;
  31. if(t.d!=dis[x])continue;
  32. for(i=h[x];i;i=nex[i]){
  33. if(dis[x]+v[i]<dis[to[i]]){
  34. dis[to[i]]=dis[x]+v[i];
  35. q.push(to[i]);
  36. }
  37. }
  38. }
  39. }
  40. const int g4[4][2]={{0,1},{0,-1},{1,0},{-1,0}},g8[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
  41. int d[3][410],n,m;
  42. vector<string>mp;
  43. bool ok(int x,int y){
  44. return 0<=x&&x<n&&0<=y&&y<m;
  45. }
  46. bool edge(int x,int y){
  47. return ok(x,y)&&(x==0||x==n-1||y==0||y==m-1);
  48. }
  49. void dfs(int fx,int fy,int x,int y,int s){
  50. int i,tx,ty;
  51. if(mp[x][y]=='A')return;
  52. add(s,x*m+y+1,0);
  53. add(x*m+y+1,s,mp[x][y]=='.');
  54. for(i=0;i<4;i++){
  55. tx=x+g4[i][0];
  56. ty=y+g4[i][1];
  57. if((tx!=fx||ty!=fy)&&edge(tx,ty))dfs(x,y,tx,ty,s);
  58. }
  59. }
  60. class Block3Checkers{
  61. public:
  62. int blockThem(vector<string>mp){
  63. int i,j,k,x,y,f,s[3],ans;
  64. ::mp=mp;
  65. n=mp.size();
  66. m=mp[0].length();
  67. s[0]=n*m+1;
  68. s[1]=n*m+2;
  69. s[2]=n*m+3;
  70. f=0;
  71. for(i=0;i<m;i++){
  72. if(mp[0][i]=='A'){
  73. if((i&&mp[0][i-1]=='A')||(i<m-1&&mp[0][i+1]=='A')||mp[1][i]=='A')return 100;
  74. if(i==0)
  75. dfs(0,0,1,0,s[f]);
  76. else
  77. dfs(0,i,0,i-1,s[f]);
  78. f++;
  79. }
  80. if(mp[n-1][i]=='A'){
  81. if((i&&mp[n-1][i-1]=='A')||(i<m-1&&mp[n-1][i+1]=='A')||mp[n-2][i]=='A')return 100;
  82. if(i==m-1)
  83. dfs(n-1,m-1,n-2,m-1,s[f]);
  84. else
  85. dfs(n-1,i,n-1,i+1,s[f]);
  86. f++;
  87. }
  88. }
  89. for(i=1;i<n-1;i++){
  90. if(mp[i][0]=='A'){
  91. if(mp[i-1][0]=='A'||mp[i+1][0]=='A')return 100;
  92. dfs(i,0,i+1,0,s[f]);
  93. f++;
  94. }
  95. if(mp[i][m-1]=='A'){
  96. if(mp[i-1][m-1]=='A'||mp[i+1][m-1]=='A')return 100;
  97. dfs(i,m-1,i-1,m-1,s[f]);
  98. f++;
  99. }
  100. }
  101. for(i=0;i<n;i++){
  102. for(j=0;j<m;j++){
  103. if(mp[i][j]!='A'){
  104. for(k=0;k<8;k++){
  105. x=i+g8[k][0];
  106. y=j+g8[k][1];
  107. if(ok(x,y)&&mp[x][y]!='A')add(i*m+j+1,x*m+y+1,mp[i][j]=='.');
  108. }
  109. }
  110. }
  111. }
  112. for(i=0;i<3;i++){
  113. dijk(s[i]);
  114. memcpy(d[i],dis,sizeof(dis));
  115. }
  116. ans=n*m;
  117. for(i=0;i<n;i++){
  118. for(j=0;j<m;j++){
  119. if(mp[i][j]!='A'){
  120. x=i*m+j+1;
  121. ans=min(ans,d[0][x]+d[1][x]+d[2][x]+(mp[i][j]=='.'));
  122. }
  123. }
  124. }
  125. return ans;
  126. }
  127. };
  128. /*
  129. int main(){
  130. vector<string>vt;
  131. char s[30];
  132. Block3Checkers cl;
  133. while(~scanf("%s",s))vt.push_back(s);
  134. printf("%d",cl.blockThem(vt));
  135. }
  136. */

[TCO2013]Block3Checkers的更多相关文章

  1. [TCO2013]TrickyInequality

    $\newcommand{stirf}[2]{{{#1}\brack{#2}}}$$\newcommand{stirs}[2]{{{#1}\brace{#2}}}$题意:$\sum\limits_{i ...

  2. [TCO2013]LitPanels

    题意:一个$n\times m$的无色网格,你可以在其中选择两个$x\times y$的子矩形并在其中将其中任意的格子涂上颜色,问最终能得到多少种不同的网格 做这题会用到一个概念叫包围盒(boundi ...

  3. [TCO2013]DirectionBoard

    题意:给一个网格,每个格子有一个方向表示在这个格子上要往哪个方向走,你可以改变某些格子的方向,问最少多少次操作使得从任意格子出发都能回到这个格子 woc这都不会我还是回家种田去吧... 题目的要求是改 ...

随机推荐

  1. CSS(Cascading Style Shee)

    1.CSS是Cascading Style Sheet这个几个英文单词的缩写,翻译成中文是“层叠样式表”的意思 CSS能让网页制作者有效的定制.改善网页的效果. CSS是对HTML的补充,网页设计师曾 ...

  2. 移动端 H5 页面注意事项

    1. 单个页面内容不能过多 设计常用尺寸:750 x 1334 / 640 x 1134,包含了手机顶部信号栏的高度. 移动端H5活动页面常常需要能够分享到各种社交App中,常用的有 微信.QQ 等. ...

  3. 制作Solaris系统的USB启动盘

    制作方法: 1. wget http://192.168.2.5/surefiler-installer/2011-12-09/devel-2011.12.9.tgz 2. cd /root tar  ...

  4. 使用Redirector插件解决googleapis公共库加载的问题【转】

    转自:http://www.cnblogs.com/kari/p/5860371.html 最近访问一些面向国外的网站总是会出现ajax.googleaips.com无法加载的情况.以下为加载stac ...

  5. 3.Python3标准库--数据结构

    (一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...

  6. FineReport——笔记

    1填报分页:需要在填报预览下的链接后添加:&__cutpage__=v:

  7. P2327

    code[class*="language-"] { padding: .1em; border-radius: .3em; white-space: normal; backgr ...

  8. 15:django 缓存架构

    动态网站的一个基本权衡就是他们是动态的,每次一个用户请求一个页面,web服务器进行各种各样的计算-从数据库查询到模板渲染到业务逻辑-从而生成站点访问者看到的页面.从处理开销的角度来看,相比标准的从文件 ...

  9. LeetCode解题报告—— 4Sum & Remove Nth Node From End of List & Generate Parentheses

    1. 4Sum Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + ...

  10. hdu 4632(区间dp)

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...