1046 Shortest Distance (20 分)
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (in [3,1
0
5
0^5
05 ]), followed by N integer distances
D
1
D_1
D1
D
2
D_2
D2⋯
D
N
D_N
DN, where
D
i
D_i
Di is the distance between the i-th and the (i+1)-st exits, and
D
N
D_N
DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (
≤
1
0
4
≤10^4
≤104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than
1
0
7
10^7
107
Output Specification:
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
Sample Input:
5 1 2 4 14 9
3
1 3
2 5
4 1
Sample Output:
3
10
7
解析
这题有些难
exit的数量最大为
1
0
5
10^5
105。而查询的数量最大为
1
0
4
10^4
104。而Time Limit是100ms。所以用普通方法肯定会超时。必须优化。
exit是构成一个圆环的,如上图:所以可以顺时针走,也可以逆时针走。题目要求的是最短路径。
其中:顺时针走的距离+逆时针走的距离 = 走一圈的距离。所以这里可以优化。
举个例子:从2走到4,可以变为从1走到4的距离减去从1走到2的距离。所以我们可以存储从1到其他结点的距离。这样:又优化了一次。
经过上面的改良:可以从O(N)变为O(1).这样就不会超时了。
Code:
#include<vector>
#include<iostream>
#include<utility>
using namespace std;
int main()
{
int N, M,Circule=0;
cin >> N;
vector<int> A(N + 1, 0),distance(N+1,0);
for (int i = 1; i <= N; i++) {
cin >> A[i];
Circule += A[i];
distance[i] = distance[i-1]+A[i];
}
cin >> M;
pair<int, int> A2B;
while (M--) {
cin >> A2B.first >> A2B.second;
if (A2B.first > A2B.second)
swap(A2B.first, A2B.second);
int shortest1 = distance[A2B.second-1]-distance[A2B.first-1];
int shortest2 = Circule-shortest1;
cout<<(shortest1>shortest2?shortest2:shortest1)<<endl;
}
}