将一个节点扩展成为八个节点
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct my{
int v;
int next;
int dist;
};
struct node{
int v;
int dist;
bool operator < (const node& rhs)const {
return dist>rhs.dist;
}
};
const int nil=(1<<29);
const int maxn=200;
const int maxn1=200000;
int R,C,sx,sy,ex,ey;
int n;
int fa;
int adj[maxn1];
my bian[maxn1*2];
int d[maxn1];
int vis[maxn1];
int tu[maxn][maxn][4];
int num[maxn][maxn][4][2];
const int up=0,left=1,down=2,right=3;
const int dir[4]={2,3,0,1};
const int dx[4]={-1,0,1,0};
const int dy[4]={0,-1,0,1};
int read(){
int x;
scanf("%d",&x);
return x;
}
void myinsert(int u,int v,int zhi){
bian[++fa].v=v;
bian[fa].dist=zhi;
bian[fa].next=adj[u];
adj[u]=fa;
}
void init(){
memset(bian,-1,sizeof(bian));
memset(adj,-1,sizeof(adj));
memset(num,0,sizeof(num));
fa=0;
}
bool cango(int r,int c,int dir){
if(r<0||r>=R||c<0||c>=C) return false;
return tu[r][c][dir]>0;
}
int getnode(int r,int c,int dirr,int doubled){
int x=num[r][c][dirr][doubled];
if(x==0) num[r][c][dirr][doubled]=x=++n;
return x;
}
void dike(){
priority_queue<node>q;
for (int i=0;i<=n;i++) d[i]=nil;
node u;
u.v=0;
u.dist=0;
q.push(u);
d[0]=0;
memset(vis,0,sizeof(vis));
while(!q.empty()){
u=q.top(); q.pop();
int v=u.v;
if(vis[v]) continue;
vis[v]=true;
for (int i=adj[v];i!=-1;i=bian[i].next){
int uu=bian[i].v;
if(d[uu]>d[v]+bian[i].dist){
d[uu]=d[v]+bian[i].dist;
node pp;
pp.v=uu;
pp.dist=d[uu];
q.push(pp);
}
}
vis[v]=false;
}
}
int main(){
int cas=0;
while(scanf("%d%d%d%d%d%d",&R,&C,&sx,&sy,&ex,&ey)==6&&R!=0){
sx--,sy--,ex--,ey--;
init();
for (int r=0;r<R;r++){
for (int c=0;c<C-1;c++) tu[r][c][right]=tu[r][c+1][left]=read();
if(r!=R-1)
for (int c=0;c<C;c++) tu[r][c][down]=tu[r+1][c][up]=read();
}
n=0;
for (int i=0;i<4;i++) {
if(cango(sx,sy,i)){
myinsert(0,getnode(sx+dx[i],sy+dy[i],i,1),tu[sx][sy][i]*2);
}
}
for (int r=0;r<R;r++){
for (int c=0;c<C;c++){
for (int dirr=0;dirr<4;dirr++) if(cango(r,c,dir[dirr])){
for (int newdirr=0;newdirr<4;newdirr++) if(cango(r,c,newdirr)){
for (int doubled=0;doubled<2;doubled++){
int newx=dx[newdirr]+r;
int newy=dy[newdirr]+c;
int v=tu[r][c][newdirr],newdoubled=0;
if(dirr!=newdirr){
if(!doubled) v+=tu[r][c][dir[dirr]];
v+=tu[r][c][newdirr],newdoubled=1;
}
myinsert(getnode(r,c,dirr,doubled),getnode(newx,newy,newdirr,newdoubled),v);
}
}
}
}
}
dike();
int ans=nil;
for (int dirr=0;dirr<4;dirr++){
if(cango(ex,ey,dir[dirr])){
for (int doubled=0;doubled<2;doubled++){
// printf("%d\n",getnode(ex,ey,dirr,doubled));
int v=d[getnode(ex,ey,dirr,doubled)];
if(!doubled) v+=tu[ex][ey][dir[dirr]];
ans=min(ans,v);
}
}
}
printf("Case %d: ",++cas);
if(ans==nil) printf("Impossible\n");
else printf("%d\n",ans);
//for (int i=0;i<n;i++) printf("%d\n",d[i]);
}
return 0;
}