题意:i -> j 的花费为|i - j| 如果有ai=j,那么i ->j的花费为1,分别求出第一个点到所有的点的最小花费
题解:建设此时在点d,那么从d点出发花费为1可到达点d-1,d+1以及ad,用bfs搜索一遍就行。
#include <iostream> #include <cstdio> #include <queue> #include <cstring> using namespace std; #define maxn 200005 #define INF 0x3f3f3f3f int a[maxn]; int dis[maxn]; bool vis[maxn]; queue<int>q; void solve() { memset(dis,INF,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[1]=0; vis[0]=vis[1]=1; q.push(1); while(!q.empty()) { int d=q.front(); q.pop(); if(dis[d+1]>dis[d]+1) { dis[d+1]=dis[d]+1; if(!vis[d+1]) q.push(d+1); vis[d+1]=1; } if(dis[a[d]]>dis[d]+1) { dis[a[d]]=dis[d]+1; if(!vis[a[d]]) q.push(a[d]); vis[a[d]]=1; } if(dis[d-1]>dis[d]+1) { dis[d-1]=dis[d]+1; if(!vis[d-1]) q.push(d-1); vis[d-1]=1; } } } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); solve(); printf("%d",dis[1]); for(int i=2;i<=n;i++) printf(" %d", dis[i]); printf(" "); return 0; }