B. Mike and Shortcuts
time limit per test
memory limit per test
input
output
Recently, Mike was very busy with studying for exams and contests. Now he is going to chill a bit by doing some sight seeing in the city.
n intersections numbered from 1 to n. Mike starts walking from his house located at the intersection number 1 and goes along some sequence of intersections. Walking from intersection number i to intersection j requires |i - j| units of energy. The total energy spent by Mike to visit a sequence of intersections p1 = 1, p2, ..., pk is equal to
units of energy.
shortcut is a special path that allows Mike walking from one intersection to another requiring only 1 unit of energy. There are exactly n shortcuts in Mike's city, the ith of them allows walking from intersection i to intersection ai (i ≤ ai ≤ ai + 1) (but not in the opposite direction), thus there is exactly one shortcut starting at each intersection. Formally, if Mike chooses a sequence p1 = 1, p2, ..., pk then for each 1 ≤ i < k satisfying pi + 1 = api and api ≠ pi Mike will spend only 1 instead of |pi - pi + 1| walking from the intersection pi to intersection pi + 1. For example, if Mike chooses a sequencep1 = 1, p2 = ap1, p3 = ap2, ..., pk = apk - 1, he spends exactly k - 1
1 ≤ i ≤ n Mike is interested in finding minimum possible total energy of some sequence p1 = 1, p2, ..., pk = i.
Input
n (1 ≤ n ≤ 200 000)
n integers a1, a2, ..., an (i ≤ ai ≤ n ,
, describing shortcuts of Mike's city, allowing to walk from intersection i to intersection ai using only 1 unit of energy. Please note that the shortcuts don't allow walking in opposite directions (from ai to i).
Output
n integers m1, m2, ..., mn, where mi denotes the least amount of total energy required to walk from intersection 1 to intersection i.
Examples
input
32 2 3
output
0 1 2
input
51 2 3 4 5
output
0 1 2 3 4
input
74 4 4 4 7 7 7
output
0 1 2 1 2 3 3
用宽搜求出从1出发到每个点的最短距离。用num[i]表示从i到num[i]需要1 energy,则从i点移到下一个点时,可以i+1, i-1, i = num[i]
#include <bits/stdc++.h>
using namespace std;
int num[200005], ans[2000005];
int main(){
// freopen("in.txt", "r", stdin);
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", num+i);
memset(ans, -1, sizeof(ans));
ans[1] = 0;
queue<int> q;
q.push(1);
while(!q.empty()){
int s = q.front();
q.pop();
for(int i = -1; i <= 1; ++i){
if(i == 0)
continue;
int d = s + i;
if(d >= 1 && d <= n && ans[d] == -1){
ans[d] = ans[s] + 1;
q.push(d);
}
}
int d = num[s];
if(ans[d] == -1){
ans[d] = ans[s] + 1;
q.push(d);
}
}
printf("%d", ans[1]);
for(int i = 2; i <= n; i++)
printf(" %d", ans[i]);
puts("");
return 0;
}