【最短路】UVALive - 4128 Steam Roller

最短路

  1 //Izayoi bless me
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<cctype>
  7 #include<cmath>
  8 #include<limits.h>
  9 #include<iomanip>
 10 #include<cstring>
 11 #include<fstream>
 12 #include<string>
 13 #include<queue>
 14 #include<stack>
 15 #include<set>
 16 #include<map>
 17 #include<vector>
 18 using namespace std;
 19 const double pi = 4.0 * atan(1.0);
 20 typedef signed long long LL;
 21 #define clr(x) memset(x,0,sizeof(x))
 22 #define clro(x) memset(x,-1,sizeof(x))
 23 typedef pair<int,int> pii;
 24 const int inf = 1000000000;
 25 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 26 #define sf scanf
 27 #define pf printf
 28 const int maxn = 111;
 29 const int maxm = 111111;
 30 const int dx[] = { -1, 0, 1, 0 };
 31 const int dy[] = { 0, -1, 0, 1 };
 32 const int UP = 0, DOWN = 2, LEFT = 1, RIGHT = 3;
 33 int inv[] = { 2, 3, 0, 1 };
 34 int id[maxn][maxn][4][2];
 35 int w[maxn][maxn][4];
 36 int tot,n,m,c1,r1,c2,r2;
 37 int T;
 38 
 39 int ID( int x, int y, int dir, int black){
 40     int &z = id[x][y][dir][black];
 41     if( z == 0 ) z = ++tot;
 42     return z;
 43 }// 返回该状态的编号
 44 
 45 bool cango( int x, int y, int dir){
 46     if( x < 0 || y < 0 || x >= n || y >= m ) return false;
 47     return w[x][y][dir] > 0 ;
 48 }// 从x,y出发,前往dir方向是否可行
 49 
 50 int readint(){ int x; cin>>x; return x; }
 51 
 52 struct Edge{
 53     int v,len;
 54     Edge( int _v, int _len){
 55         v = _v, len = _len;
 56     };
 57 };
 58 struct node{
 59     int d,u;
 60     node( int _d, int _u ){
 61         d = _d, u = _u;
 62     }
 63     friend bool operator < ( const node &a, const node &b){
 64         return a.d > b.d;
 65     }
 66 };
 67 struct Dijkstra{
 68     priority_queue<node>Q;
 69     vector<Edge>edges[maxm];
 70     int dis[maxm], vis[maxm];
 71     void clear(){
 72         for( int i=0; i<maxm; ++i) edges[i].clear();
 73         while( !Q.empty() ) Q.pop();
 74     };
 75     void addedge( int u, int v, int len){
 76         edges[u].push_back( Edge(v,len) );
 77     }
 78     void dijkstra( int x ){
 79         clr(vis);
 80         for( int i=0; i<maxm; ++i) dis[i] = inf;
 81         dis[x] = 0;
 82         Q.push( node(0,x) );
 83         while( !Q.empty() ){
 84             node k = Q.top(); Q.pop();
 85             int u = k.u;
 86             if( vis[u] ) continue;
 87             vis[u] = true;
 88             for( unsigned int i=0; i<edges[u].size(); ++i){
 89                 Edge &e = edges[u][i];
 90                 if( dis[e.v] > dis[u]+e.len ){
 91                     dis[e.v] = dis[u] + e.len;
 92                     Q.push( node(dis[e.v], e.v ) );
 93                 }
 94             }
 95         }
 96     };
 97 }g;// 最短路部分,就不解释了
 98 
 99 void init(){
100     g.clear();
101     tot = 0;
102     clr(id); clr(w);
103 }// 初始化
104 
105 void input(){
106     for( int r=0; r<n; ++r){
107         for( int c=0; c< m-1; ++c)
108             w[r][c][RIGHT] = w[r][c+1][LEFT] = readint();
109         if( r != n-1 ) for( int c =0; c<m; ++c)
110             w[r][c][DOWN] = w[r+1][c][UP] = readint();
111     }
112 }//读入边的情况,并存储
113 
114 void doit(){
115     for( int dir=0; dir<4; ++dir) if( cango(r1,c1,dir) )
116         g.addedge( 0, ID(r1+dx[dir] , c1+dy[ dir] , dir, 1 ) , w[r1][c1][dir]*2 );
117 
118     for( int r=0; r<n; ++r)
119         for( int c=0; c<m; ++c)
120             for( int dir=0; dir<4; ++dir) if( cango( r,c, inv[dir] ) )
121                 for( int newdir=0; newdir<4; ++newdir) 
122                     if( cango(r,c,newdir) )
123                         for( int black=0; black<2; ++black){
124                             int newr = r + dx[newdir]; 
125                             int newc = c + dy[newdir];
126                             int v = w[r][c][newdir], newblack = 0;
127                             if( dir != newdir){
128                                 if( !black ) v += w[r][c][inv[ dir] ];
129                                 newblack = 1; v+= w[r][c][newdir];
130                             }
131                             g.addedge( ID(r,c,dir,black), ID(newr,newc,newdir,newblack) , v );
132                         }
133 } // 从每一个状态向后继状态连边
134 // (r,c,dir,black)代表上一步从哪个方向移动到这个点,以及移动到这个点的这条边的权值是否已经加倍
135 
136 void solve(){
137     g.dijkstra(0);
138     int ans = inf;
139     for( int dir=0; dir<4; ++dir) if( cango(r2,c2,inv[dir]) )
140         for( int black=0; black<2; ++black){
141             int v = g.dis[ ID(r2,c2,dir,black) ];
142             if( !black) v+= w[r2][c2][ inv[ dir] ];
143             ans = min(ans, v );
144         }
145     cout<<"Case "<<++T<<": ";
146     if( ans == inf) cout<<"Impossible"<<endl;
147     else cout<<ans<<endl;
148 }
149 
150 int main(){
151     std::ios::sync_with_stdio(false);
152     T = 0;
153     while( cin>>n>>m>>r1>>c1>>r2>>c2 && n ){
154         --c1,--c2,--r1,--r2;
155         init();
156         input();
157         doit();
158         solve();
159     }
160 }

 

posted @ 2012-12-26 22:47  masterhe  阅读(364)  评论(0)    收藏  举报