At each location, the current flows in some direction. The captain can choose to either go with the flow of the current, using no energy, or to move one square in any other direction, at the cost of one energy unit. The boat always moves in one of the following eight directions: north, south, east, west, northeast, northwest, southeast, southwest. The boat cannot leave the boundary of the lake. You are to help him devise a strategy to reach the destination with the minimum energy consumption.
7 0 1 \|/ 6-*-2 /|\ 5 4 3The line after the grid contains a single integer n , the number of trips to be made, which is at most 50. Each of the following n lines describes a trip using four integers rs , cs , rd , cd , giving the row and column of the starting point and the destination of the trip. Rows and columns are numbered starting with 1.
5 5 04125 03355 64734 72377 02062 3 4 2 4 2 4 5 1 4 5 3 3 4
0 2 1
Ondřej Lhoták, Richard Peng
这题写了两种姿势,
第一种是每次到某点的距离更新后,把该点入队。出队时判断,如果出队距离大于当前求得的最短距离,则直接抛弃掉。否则,更新当前最短距离,然后以该状态拓展新的状态。
第二种是每次到某点的距离更新后,把该点入队,同时更新最短距离。出队时判断,如果出队距离大于当前求得的最短距离,则直接抛弃掉。否则,拓展新的状态。
第一种跑了2.95秒(差点Tle了),第二种1.05秒。这是为什么呢?因为第一种中入队的节点会更多!贴上第二种的代码。实际上两种写法只有一点点的差别,但时间上却会差很多!
#include <cstdio> #include <algorithm> #include <vector> #include <map> #include <queue> #include <iostream> #include <stack> #include <set> #include <cstring> #include <stdlib.h> #include <cmath> using namespace std; typedef long long LL; typedef pair<int, int> P; const int maxn = 1000 + 5; const int INF = 1000000000; int r, c; char M[maxn][maxn]; int vis[maxn][maxn]; const int cx[] = {-1, -1, 0, 1, 1, 1, 0, -1}; const int cy[] = {0, 1, 1, 1, 0, -1, -1, -1}; struct Node{ int x, y, dis; Node(int x, int y, int dis){ this -> x = x; this -> y = y; this -> dis = dis; } bool operator < (const Node& e) const{ return e.dis < dis; } }; bool check(int x, int y){return x > 0 && x <= r && y > 0 && y <= c;} priority_queue<Node> pq; int solve(int sx, int sy, int ex, int ey){ for(int i = 0;i < maxn;i++){ for(int j = 0;j < maxn;j++){ vis[i][j] = INF; } } while(!pq.empty()) pq.pop(); pq.push(Node(sx, sy, 0)); while(!pq.empty()){ Node top = pq.top(); pq.pop(); int x = top.x; int y = top.y; int dis = top.dis; if(dis > vis[x][y]) continue; vis[x][y] = dis; if(x == ex && y == ey) return dis; for(int i = 0;i < 8;i++){ int tx = x+cx[i]; int ty = y+cy[i]; int dist = dis + (i==(M[x][y]-'0')?0:1); if(check(tx, ty) && dist < vis[tx][ty]){ vis[tx][ty] = dist; pq.push(Node(tx, ty, dist)); } } } } int main(){ while(scanf("%d%d", &r, &c) != EOF){ for(int i = 1;i <= r;i++){ scanf("%s", M[i]+1); } int q; scanf("%d", &q); while(q--){ int sx, sy, ex, ey; scanf("%d%d%d%d", &sx, &sy, &ex, &ey); int ans = solve(sx, sy, ex, ey); printf("%d\n", ans); } } return 0; }