标签:
题意:求从1开始的到所有点的最短路。
分析:设图中的两个点u,v, 则dis[u][v] = abs(u-v) 或 dis[u][v] = 1。
其实换个角度想就可以发现每次运动消耗的能量都是1。由于每一单位时间运动消耗的能量都是1。
状态的转移有三个:1、向前走一步。2、先后走一步。3、走捷径。
/************************************************ Author :DarkTong Created Time :2016/7/7 16:09:39 File Name :B.cpp *************************************************/ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> #define INF 0x3f3f3f3f #define esp 1e-9 typedef long long LL; using namespace std; const int maxn = 200000 + 10; int d[maxn], sh[maxn], vis[maxn], n; void solve() { memset(d, INF, sizeof(d)); d[1]=0; queue<int> q; q.push(1); vis[1]=vis[0]=1; while(!q.empty()) { int t = q.front(); q.pop(); if(d[t+1]>d[t]+1) { d[t+1]=d[t]+1; if(!vis[t+1])q.push(t+1); vis[t+1]=1; } if(d[sh[t]]>d[t]+1) { d[sh[t]]=d[t]+1; if(!vis[sh[t]])q.push(sh[t]); vis[sh[t]]=1; } if(d[t-1]>d[t]+1) { d[t-1]=d[t]+1; if(!vis[t-1])q.push(t-1); vis[t-1]=1; } } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d", &n); for(int i=1;i<=n;++i) scanf("%d", &sh[i]); solve(); for(int i=1;i<=n;++i) printf("%d%c", d[i], i==n?‘\n‘:‘ ‘); return 0; }
Codeforces 689B - Mike and Shortcuts
标签:
原文地址:http://www.cnblogs.com/DarkTong/p/5653031.html