Finding the shortest-path tree in the upper left-hand corner to the upper-left corner of each point to be protected, the optimal solution must have circled them.
Then each point is split into four points, between four points if it does not cross the shortest tree edge of the tree, then even 0 right side.
Each need to protect the point four weeks 4 points are not accessible, to find the shortest is the answer.
Time Complexity $o (Nm\log (NM)) $.
#include <cstdio> #include <algorithm> #include <queue>using namespace Std;typedef long ll; typedef pair<ll,int>p;const INT N=410,m=2600000;const ll Inf=1ll<<60;int n,m,i,j,k,x,y,a[n][n],b[n][n],c N [N];int tot,f[n][n],x[n*n],y[n*n],pre[n][n];ll d[n][n];bool vis[n][n],mark[n][n][4],del[n*n*4];p riority_queue< p,vector<p>,greater<p> >q;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 ext (int x,int y,ll Z,int p) {if (!f[x][y]| | D[X][Y]<=Z) return; D[x][y]=z,pre[x][y]=p; Q.push (P (Z,f[x][y]));} void Dfs (int x,int y) {if (x==1&&y==1) return; if (Vis[x][y]) return; Vis[x][y]=1; int x=x,y=y,d=pre[x][y]; Mark[x][y][d]=1; if (! D) x--; if (d==1) x + +; if (d==2) y--; if (d==3) y++; Mark[x][y][d^1]=1; DFS (x, y);} namespace G{int f[n][n][4],x[n*n*4],y[n*n*4],z[n*n*4];int g[n*n*4],v[m],w[m],nxt[m],ed;ll d[N*N*4];inline void Add (int x,int y,int z) {if (del[x]| | Del[y]) return; v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed; v[++ed]=x;w[ed]=z;nxt[ed]=g[y];g[y]=ed;} void work () {Q.push (P (d[2]=0,2)); while (! Q.empty ()) {P t=q.top (); Q.pop (); if (D[x=t.second]<t.first) continue; for (I=g[x];i;i=nxt[i]) if (D[x]+w[i]<d[v[i]]) Q.push (P (D[v[i]]=d[x]+w[i],v[i])); } printf ("%lld", D[3]);}} int main () {read (n), read (m); for (i=1;i<=n;i++) for (j=1;j<=m;j++) read (a[i][j]); for (i=1;i<=n;i++) for (j=1;j<=m+1;j++) read (b[i][j]); for (i=1;i<=n+1;i++) for (j=1;j<=m;j++) read (c[i][j]); for (i=1;i<=n+1;i++) for (j=1;j<=m+1;j++) f[i][j]=++tot,d[i][j]=inf,x[tot]=i,y[tot]=j; Q.push (P (d[1][1]=0,1)); while (! Q.empty ()) {P t=q.top (); Q.pop (); if (D[x=x[t.second]][y=y[t.second]]<t.first) continue; Ext (x+1,y,d[x][y]+b[x][y],0); Ext (x-1,y,d[x][y]+b[x-1][y],1); Ext (x,y+1,d[x][y]+c[x][y],2); Ext (x,y-1,d[x][y]+c[x][y-1],3); } for (i=1;i<=n;i++) for (j=1;j<=m;j++) if (A[i][j]) DFS (I,J); for (Tot=0,i=1;i<=n+1;i++) for (j=1;j<=m+1;j++) for (k=0;k<4;k++) {g::f[i][j][k]=++tot,g::x[tot]=i,g::y[tot]=j,g::z[tot]= K G::d [Tot]=inf; } for (del[1]=i=1;i<=n;i++) for (j=1;j<=m;j++) if (A[i][j]) {del[g::f[i][j][3]]=1; Del[g::f[i+1][j][1]]=1; Del[g::f[i][j+1][2]]=1; Del[g::f[i+1][j+1][0]]=1; } for (i=1;i<=n;i++) for (j=1;j<=m+1;j++) {G::add (g::f[i][j][2],g::f[i+1][j][0],b[i][j]); G::add (G::f[i][j][3],g::f[i+1][j][1],b[i][j]); } for (i=1;i<=n+1;i++) for (j=1;j<=m;j++) {G::add (g::f[i][j][1],g::f[i][j+1][0],c[i][j]); G::add (G::f[i][j][3],g::f[i][j+1][2],c[i][j]); } for (i=1;i<=n+1;i++) for (j=1;j<=m+1;j++) {if (!mark[i][j][0]) G::add (g::f[i][j][0],g::f[i][j][1],0); if (!mark[i][j][1]) G::add (g::f[i][j][2],g::f[i][j][3],0); if (!mark[i][j][2]) G::add (g::f[i][j][0],g::f[i][j][2],0); if (!mark[i][j][3]) G::add (g::f[i][j][1],g::f[i][j][3],0); } g::work (); return 0;}
bzoj4356:ceoi2014 Wall