给出一个长度为 (n) 的序列 (a),当你在第 (i) 号位置是,你可以一步调到 (i-a_i) 和 (i+a_i),前提是 (1 le) 跳到的位置 (le n),对于每一个位置 (i),你想知道最少需要多少步可以到达一个位置 (j),使得 (a_j) 与 (a_i) 的奇偶性不同
Solution
第 (i-a_i) 个点,第 (i+a_i) 个点向第 (i) 个点连边,费用为 (1),所有奇数点向 (n+1) 连边,费用为 (0),所有偶数点向 (n+2) 连边,费用为 (0)
分别以 (n+1),(n+2) 为起点跑最短路即可
#include <bits/stdc++.h>
using namespace std;
#define reset(x) memset(x,0,sizeof x)
#define reset3f(x) memset(x,0x3f,sizeof x)
namespace sp {
const int N=1e+6+5;
vector<pair<int,int> > g[N];
int n,v0=1,d[N],v[N];
void make(int t1,int t2,int t3) {
g[t1].push_back(make_pair(t2,t3));
}
void reset_graph() {
for(int i=0;i<=n;i++) g[i].clear();
}
void solve() {
queue <int> qu;
reset(v); reset3f(d);
d[v0]=0; v[v0]=1; qu.push(v0);
while(qu.size()) {
int p=qu.front();
qu.pop();
v[p]=0;
for(int i=0;i<g[p].size();i++) {
int q=g[p][i].first,w=g[p][i].second;
if(d[q]>d[p]+w) {
d[q]=d[p]+w;
if(!v[q]) qu.push(q), v[q]=1;
}
}
}
}
}
int n,a[200005],ans[200005];
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) {
if(i+a[i]<=n) sp::make(i+a[i],i,1);
if(i-a[i]>=1) sp::make(i-a[i],i,1);
if(a[i]&1) sp::make(n+1,i,0);
else sp::make(n+2,i,0);
}
sp::v0=n+1;
sp::solve();
for(int i=1;i<=n;i++) if(a[i]%2==0) ans[i]=sp::d[i];
sp::v0=n+2;
sp::solve();
for(int i=1;i<=n;i++) if(a[i]%2) ans[i]=sp::d[i];
for(int i=1;i<=n;i++) {
if(ans[i]>=1e9) cout<<-1<<" ";
else cout<<ans[i]<<" ";
}
}