hihoCoder 1138-Islands Travel | bitJoy > code
There are N islands on a planet whose coordinates are (X1, Y1), (X2, Y2), (X3, Y3) ..., (XN, YN). You starts at the 1st island (X1, Y1) and your destination is the n-th island (XN, YN). Travelling between i-th and j-th islands will cost you min{|Xi-Xj|, |Yi-Yj|} (|a| denotes the absolute value of a. min{a, b} denotes the smaller value between a and b) gold coins. You want to know what is the minimum cost to travel from the 1st island to the n-th island.
输入
Line 1: an integer N.
Line 2~N+1: each line contains two integers Xi and Yi.
For 40% data, N<=1000,0<=Xi,Yi<=100000.
For 100% data, N<=100000,0<=Xi,Yi<=1000000000.
输出
Output the minimum cost.
样例输入
3
2 2
1 7
7 6
样例输出
2
本题实质上是单源最短路径问题,只是两点间的距离需要自己算。我先后尝试了Dijkstra算法和朴素SPFA算法,都超时,后来参考这篇博客,在SPFA之前需要对数据进行预处理。
原始SPFA时,点(x,y)和其余n-1个点的边都需要尝试,这样计算量就很大,但是因为距离函数是min{|Xi-Xj|, |Yi-Yj|}这样的,和点(x,y)"距离"最近的点(x',y')是那些x'和x最近或者y'和y最近的点。所以点(x,y)实际上只需要尝试4条边,分别是靠近x的前后两个点和靠近y的上下两个点。
所以我们需要对所有点分别按x和y排序,然后重新构造一个图,这个图中,每个点只和另外4个点有边,这样使得图的复杂度大幅下降,再使用SPFA就不会超时了。
There are N islands on a planet whose coordinates are (X1, Y1), (X2, Y2), (X3, Y3) ..., (XN, YN). You starts at the 1st island (X1, Y1) and your destination is the n-th island (XN, YN). Travelling between i-th and j-th islands will cost you min{|Xi-Xj|, |Yi-Yj|} (|a| denotes the absolute value of a. min{a, b} denotes the smaller value between a and b) gold coins. You want to know what is the minimum cost to travel from the 1st island to the n-th island.
输入
Line 1: an integer N.
Line 2~N+1: each line contains two integers Xi and Yi.
For 40% data, N<=1000,0<=Xi,Yi<=100000.
For 100% data, N<=100000,0<=Xi,Yi<=1000000000.
输出
Output the minimum cost.
样例输入
3
2 2
1 7
7 6
样例输出
2
本题实质上是单源最短路径问题,只是两点间的距离需要自己算。我先后尝试了Dijkstra算法和朴素SPFA算法,都超时,后来参考这篇博客,在SPFA之前需要对数据进行预处理。
原始SPFA时,点(x,y)和其余n-1个点的边都需要尝试,这样计算量就很大,但是因为距离函数是min{|Xi-Xj|, |Yi-Yj|}这样的,和点(x,y)"距离"最近的点(x',y')是那些x'和x最近或者y'和y最近的点。所以点(x,y)实际上只需要尝试4条边,分别是靠近x的前后两个点和靠近y的上下两个点。
所以我们需要对所有点分别按x和y排序,然后重新构造一个图,这个图中,每个点只和另外4个点有边,这样使得图的复杂度大幅下降,再使用SPFA就不会超时了。
const int kMaxN = 100005, kINF = 0x3f;int n;typedef struct P{ int x, y;};typedef struct Node{ int value; int id; bool operator <(const Node & t)const { return value < t.value; }};Node X[kMaxN], Y[kMaxN];P points[kMaxN];int dist[kMaxN];int used[kMaxN];vector<vector<int>> path(kMaxN);inline int GetLength(int a, int b){ return min(abs(points[a].x - points[b].x), abs(points[a].y - points[b].y));}int Spfa(){ used[1] = 1; memset(dist, kINF, sizeof(dist)); dist[1] = 0; queue<int> Q; Q.push(1); while (!Q.empty()) { int u = Q.front(); Q.pop(); used[u] = 0; for (int i = 0; i < path[u].size(); i++) { int v = path[u][i]; if (dist[u] + GetLength(u, v) < dist[v]) { dist[v] = dist[u] + GetLength(u, v); if (used[v] == 0) { Q.push(v); used[v] = 1; } } } } return dist[n];}int main(){ scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d %d", &points[i].x, &points[i].y); X[i].value = points[i].x; X[i].id = i; Y[i].value = points[i].y; Y[i].id = i; } sort(X + 1, X + n + 1); sort(Y + 1, Y + n + 1); for (int i = 2; i <= n; i++) { path[X[i].id].push_back(X[i - 1].id); path[X[i - 1].id].push_back(X[i].id); } for (int i = 2; i <= n; i++) { path[Y[i].id].push_back(Y[i - 1].id); path[Y[i - 1].id].push_back(Y[i].id); } printf("%d\n", Spfa()); return 0;
}
Read full article from hihoCoder 1138-Islands Travel | bitJoy > code