https://vjudge.net/problem/UVALive-4128
大意就是给你一张格子图,r 根横线, c 根竖线。告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行。
通俗的走的规则是:车子的惯性比较大,如果你在下个路口要转弯,那么后半段就开慢了,好转弯,转弯完了之后,你要加速,那么前半段就慢了,这两种情况都会使这段路的时间加倍,但是如果一条路同时是这样,那么也只算两倍。起点这终点一个启动,一个是制动,那么和他们相连的第一条边也算两倍。问你最短时间,如果不行,就输出 “Impossible” 。
多状态转移的最短路,值得一做
#include<iostream> #include<cstdio> #include<cstring> #define ri register int #define u int #define NN 1005 namespace fast { inline u in() { u x(0),f(1); char s=getchar(); while(s<'0'||s>'9') { if(s=='-') { f=-1; } s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using fast::in; namespace spfa { #define XX 1000005 struct node { u x,y,to,is; } q[XX]; u l,r,N,M,dx[4]= {-1,0,1,0},dy[4]= {0,1,0,-1},d[NN][NN][5][2],vt[NN][NN][5][2],a[NN][NN][5][2]; node make(const u &x,const u &y,const u &to,const u &is) { node _x; _x.x=x,_x.y=y,_x.to=to,_x.is=is; return _x; } u run() { while(l<r) { node _k=q[++l]; u x=_k.x,y=_k.y,to=_k.to,is=_k.is; vt[x][y][to][is]=0; for(ri k(0); k<=3; ++k) { u nx(dx[k]+x),ny(dy[k]+y); if(nx<1||nx>N||ny<1||ny>M) continue; u z; if(is) { z=a[x][y][k][1]; if(d[x][y][to][is]+z<d[nx][ny][k][0]) { d[nx][ny][k][0]=d[x][y][to][is]+z; if(!vt[nx][ny][k][0]) { vt[nx][ny][k][0]=1,q[++r]=make(nx,ny,k,0); } } if(d[x][y][to][is]+z<d[nx][ny][k][1]) { d[nx][ny][k][1]=d[x][y][to][is]+z; if(!vt[nx][ny][k][1]) { vt[nx][ny][k][1]=1,q[++r]=make(nx,ny,k,1); } } } else { if(k^to) { continue; } else { z=a[x][y][k][0]; if(d[x][y][to][is]+z*2<d[nx][ny][k][1]) { d[nx][ny][k][1]=d[x][y][to][is]+z*2; if(!vt[nx][ny][k][1]) { vt[nx][ny][k][1]=1,q[++r]=make(nx,ny,k,1); } } if(d[x][y][to][is]+z<d[nx][ny][k][0]) { d[nx][ny][k][0]=d[x][y][to][is]+z; if(!vt[nx][ny][k][0]) { vt[nx][ny][k][0]=1,q[++r]=make(nx,ny,k,0); } } } } } } } #undef XX } using namespace spfa; namespace all { u stx,sty,edx,edy,cas; inline void solve() { while(scanf("%d%d%d%d%d%d",&N,&M,&stx,&sty,&edx,&edy)) { if(!N) break; std::memset(d,0x3f,sizeof(d)); std::memset(vt,0,sizeof(vt)); l=r=0; for(ri i(1); i<N; ++i) { for(ri j(1); j<M; ++j) { u _a(in()); if(!_a) _a=0x3f3f3f3f; a[i][j][1][0]=a[i][j+1][3][0]=_a; a[i][j][1][1]=a[i][j+1][3][1]=(_a<<1); } for(ri j(1); j<=M; ++j) { u _a(in()); if(!_a) _a=0x3f3f3f3f; a[i][j][2][0]=a[i+1][j][0][0]=_a; a[i][j][2][1]=a[i+1][j][0][1]=(_a<<1); } } for(ri j(1); j<M; ++j) { u _a(in()); if(!_a) _a=0x3f3f3f3f; a[N][j][1][0]=a[N][j+1][3][0]=_a; a[N][j][1][1]=a[N][j+1][3][1]=(_a<<1); } q[++r]=make(stx,sty,4,1); //q[++r]=make(stx,sty,2,0); //q[++r]=make(stx,sty,1,1); //q[++r]=make(stx,sty,2,1); //d[stx][sty][1][0]=a[stx][sty][1][1]; d[stx][sty][4][1]=0; //d[stx][sty][2][0]=a[stx][sty][2][1]; //d[stx][sty][1][1]=a[stx][sty][1][1]; //d[stx][sty][2][1]=a[stx][sty][2][1]; run(); u ans(std::min(d[edx][edy][0][1],std::min(d[edx][edy][1][1],std::min(d[edx][edy][2][1],d[edx][edy][3][1])))); if(ans<0x3f3f3f3f) printf("Case %d: %d ",++cas,ans); else printf("Case %d: Impossible ",++cas); } } } int main() { //freopen("x.txt","r",stdin); all::solve(); }