题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍
官方题解——一张图教你做人...
三个棋子将网格边界分成三段,添加障碍后网格中一定存在一个点使得它可以到这三段(只走障碍的路径,八连通)
所以找出这三段后分别以它们为起点跑最短路即可,经过障碍权值为$0$,经过空地权值为$1$
#include#include #include #include #include using namespace std;int h[410],nex[7010],to[7010],v[7010],M;void add(int a,int b,int c){ M++; to[M]=b; v[M]=c; nex[M]=h[a]; h[a]=M;}int dis[410];struct pr{ int x,d; pr(int u=0){x=u;d=dis[u];}}t;bool operator<(pr a,pr b){return a.d>b.d;}priority_queue q;void dijk(int x){ int i; memset(dis,63,sizeof(dis)); dis[x]=0; q.push(x); while(!q.empty()){ t=q.top(); q.pop(); x=t.x; if(t.d!=dis[x])continue; for(i=h[x];i;i=nex[i]){ if(dis[x]+v[i] mp;bool ok(int x,int y){ return 0<=x&&x <=y&&y mp){ int i,j,k,x,y,f,s[3],ans; ::mp=mp; n=mp.size(); m=mp[0].length(); s[0]=n*m+1; s[1]=n*m+2; s[2]=n*m+3; f=0; for(i=0;i vt; char s[30]; Block3Checkers cl; while(~scanf("%s",s))vt.push_back(s); printf("%d",cl.blockThem(vt));}*/