求出不使用P点时起点到终点的最短距离,求出起点到所有P点的最短距离,求出终点到所有P点的最短距离。
答案=min( 不使用P点时起点到终点的最短距离, 起点到P的最短距离+终点到P的最短距离 )
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; const int MAXN = 5100; const int INF = 1 << 30; const int dx[] = { -1, 0, 0, 1 }; const int dy[] = { 0, -1, 1, 0 }; struct node { int x, y; int cost; int id; bool operator<( const node &rhs ) const { return cost < rhs.cost; } }; int R, C, cost; char mat[MAXN][MAXN]; bool vis[MAXN][MAXN]; int index[MAXN][MAXN]; int G[2][MAXN/10]; node P[MAXN/10], start, end; int cntP; void init( ) { cntP = 1; for ( int i = 0; i < R; ++i ) for ( int j = 0; j < C; ++j ) { if ( mat[i][j] == 'P' ) { P[cntP].x = i; P[cntP].y = j; P[cntP].cost = 0; P[cntP].id = cntP; //printf( "cntP=%d [%d, %d] ", cntP, i, j ); ++cntP; } else if ( mat[i][j] == 'Y' ) { start.x = i; start.y = j; start.cost = 0; } else if ( mat[i][j] == 'C' ) { end.x = i; end.y = j; end.cost = 0; } } P[0] = start; P[0].id = 0; P[cntP] = end; P[cntP].id = cntP; //printf( "cntP = %d ", cntP ); for ( int i = 0; i <= cntP; ++i ) index[ P[i].x ][ P[i].y ] = i; return; } bool check( int x, int y ) { if ( x >= 0 && x < R && y >= 0 && y < C ) return true; return false; } int BFS( int c, node st ) { for ( int i = 0; i < R; ++i ) for ( int j = 0; j < C; ++j ) vis[i][j] = false; queue<node> Q; st.cost = 0; vis[ st.x ][ st.y ] = true; Q.push(st); while ( !Q.empty() ) { node cur = Q.front(); Q.pop(); for ( int i = 0; i < 4; ++i ) { int xx = cur.x + dx[i]; int yy = cur.y + dy[i]; if ( check( xx, yy ) && mat[xx][yy] != '#' && !vis[xx][yy] ) { node next; next.x = xx; next.y = yy; next.cost = cur.cost; next.id = index[xx][yy]; if ( mat[xx][yy] != '*' ) { int id = index[xx][yy]; G[c][id] = next.cost; } else next.cost += cost; vis[xx][yy] = true; Q.push(next); } } } return INF; } int getG() { //printf("***cntP=%d ", cntP); for ( int i = 0; i <= cntP; ++i ) { G[0][i] = INF; G[1][i] = INF; } BFS( 0, P[0] ); BFS( 1, P[cntP] ); int ans = G[0][cntP]; //printf("***ans=%d ", ans ); for ( int i = 1; i < cntP; ++i ) for ( int j = 1; j < cntP; ++j ) { if ( G[0][i] < INF && G[1][j] < INF ) ans = min( ans, G[0][i] + G[1][j] ); //printf( "ans = %d ", ans ); } return ans; } int main() { while ( scanf( "%d%d%d", &R, &C, &cost ) == 3 ) { for ( int i = 0; i < R; ++i ) scanf( "%s", mat[i] ); init(); int ans = getG(); if ( ans < INF ) printf( "%d ", ans ); else puts("Damn teoy!"); } return 0; }