B. Mike and Shortcuts(cf#361)
B. Mike and Shortcuts
time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard outputRecently, 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.
City consists of n
Of course, walking would be boring if there were no shortcuts. A 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
Before going on his adventure, Mike asks you to find the minimum amount of energy required to reach each of the intersections from his home. Formally, for each 1 ≤ i ≤ n Mike is interested in finding minimum possible total energy of some sequence p1 = 1, p2, ..., pk = i.
InputThe first line contains an integer n (1 ≤ n ≤ 200 000) — the number of Mike's city intersection.
The second line contains 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).
OutputIn the only line print n integers m1, m2, ..., mn, where mi denotes the least amount of total energy required to walk from intersection 1 to intersection i.
Examples input3
2 2 3
output
0 1 2
input
5
1 2 3 4 5
output
0 1 2 3 4
input
7
4 4 4 4 7 7 7
output
0 1 2 1 2 3 3
Note
In the first sample case desired sequences are:
1: 1; m1 = 0;
2: 1, 2; m2 = 1;
3: 1, 3; m3 = |3 - 1| = 2.
In the second sample case the sequence for any intersection 1 < i is always 1, i and mi = |1 - i|.
In the third sample case — consider the following intersection sequences:
1: 1; m1 = 0;
2: 1, 2; m2 = |2 - 1| = 1;
3: 1, 4, 3; m3 = 1 + |4 - 3| = 2;
4: 1, 4; m4 = 1;
5: 1, 4, 5; m5 = 1 + |4 - 5| = 2;
6: 1, 4, 6; m6 = 1 + |4 - 6| = 3;
7: 1, 4, 5, 7; m7 = 1 + |4 - 5| + 1 = 3.
相當於求從源點到其他所有點的最短路,只需要跑一次bfs更新每個點的鄰接點即可,之前想要直接暴力結果超時了。(要用bfs求最短路必須滿足所有邊的權值都相同)
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
const int M=2e5+7;
const int inf=1e9;
int a[M],d[M];
queue<int>q;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
d[i]=inf;
}
q.push(1);
d[1]=0;
while(!q.empty()) //bfs
{
int x=q.front();
q.pop();
if(x<n&&d[x+1]>d[x]+1)
{
d[x+1]=d[x]+1;
q.push(x+1);
}
if(x>1&&d[x-1]>d[x]+1)
{
d[x-1]=d[x]+1;
q.push(x-1);
}
if(d[a[x]]>d[x]+1)
{
d[a[x]]=d[x]+1;
q.push(a[x]);
}
}
/*for(int i=1;i<=n;i++) //暴力
{
for(int j=1;j<i;j++)
{
if(a[j]==i)
b[i]=min(b[i],b[j]+1);
if(a[j]>i)
b[i]=min(b[i],b[j]+1+a[j]-i);
b[i]=min(b[i],b[j]+i-j);
}
}*/
for(int i=1;i<n;i++)
printf("%d ",d[i]);
printf("%d\n",d[n]);
return 0;
}