It is clear that the shortest and minor short-circuiting of each point to all critical points is the answer to the short-circuit of each key point.
Set $f[i][j][0]$ means the left hand in the $i$, right hand in the $j$ solution, $f [I][j][1]$ said the left hand in $i$, right hand in $j$, and left hand has moved the right hand has not begun to move the solution, and then BFS can.
Time Complexity $o (n (n+m)) $.
#include <cstdio>const int N=1010,m=10010;int n,m,k,dmi,dma,i,j,k,x,y,z,vip[n][n],ans[n*n],e[2][n],v[m],nxt[ M],ed,h,t,q[n*n*4][5];struct p{int x, y; P () {}p (int _x,int _y) {x=_x,y=_y;}} a[n],f[n][n][2],g[n][n][2];inline void Read (int&a) {char c;while (!) ( ((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')); a=c-' 0 '; while (((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')) (a*= Ten) +=c-' 0 ';} inline void Add (Int&x,int y) {v[++ed]=y;nxt[ed]=x;x=ed;} inline int abs (int x) {return x>0?x:-x;} inline bool Check (int x,int y) {int d=abs (a[x].x-a[y].x) +abs (A[X].Y-A[Y].Y); return DMI<=D&&D<=DMA;} inline void ext (int x,int y,int z,int a,int b) {if (!z&&!check (x, y)) return; if (G[X][Y][Z].Y) return; if (f[x][y][z].y==b) return; Q[++t][0]=x,q[t][1]=y,q[t][2]=z,q[t][3]=a,q[t][4]=b; if (!F[X][Y][Z].Y) f[x][y][z]=p (A, b); else G[x][y][z]=p (A, b);} int main () {read (n), read (m), read (DMI), read (DMA); for (i=1;i<=n;i++) read (a[i].x), read (A[I].Y); Read (K); for (i=1;i<=k;i++) read (x), read (y), Vip[x][y]=i; while (m--) {read (x), read (y), read (z); Add (E[z][x],y), add (e[z][y],x); } for (i=1;i<=n;i++) Add (e[0][i],i), add (e[1][i],i); for (h=i=1;i<=n;i++) for (j=1;j<=n;j++) if (Vip[i][j]) ext (i,j,0,0,vip[i][j]); while (h<=t) {x=q[h][0],y=q[h][1],z=q[h][2],j=q[h][3]+1-z,k=q[h++][4]; for (I=e[z][z?y:x];i;i=nxt[i]) ext (z?x:v[i],z?v[i]:y,z^1,j,k); } for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (vip[i][j]) ans[vip[i][j]]=g[i][j][0].y?g[i][j][0].x:-1; for (i=1;i<=k;i++) printf ("%d\n", Ans[i]); return 0;}
BZOJ3161: The solitary boat and the Weng