LA 4128

将一个节点扩展成为八个节点

#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;
}

posted @ 2018-01-25 20:53  lmjer  阅读(120)  评论(0编辑  收藏  举报