【最短路】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 }

浙公网安备 33010602011771号