You are given an array aa consisting of nn integers. In one move, you can jump from the position ii to the position i−aii−ai (if 1≤i−ai1≤i−ai) or to the position i+aii+ai (if i+ai≤ni+ai≤n).

For each position ii from 11 to nn you want to know the minimum the number of moves required to reach any position jj such that ajaj has the opposite parity from aiai (i.e. if aiai is odd then ajaj has to be even and vice versa).

Input
The first line of the input contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of elements in aa.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n), where aiai is the ii-th element of aa.

Output
Print nn integers d1,d2,…,dnd1,d2,…,dn, where didi is the minimum the number of moves required to reach any position jj such that ajaj has the opposite parity from aiai (i.e. if aiai is odd then ajaj has to be even and vice versa) or -1 if it is impossible to reach such a position.

Example
Input
10
4 5 7 6 7 5 4 4 6 4
Output
1 1 1 2 -1 1 1 3 1 1
思路:一开始以为是记忆化搜索,就dfs,结果成环的情况不能处理。这种题目,一般进行转化,将这些数字建成图来处理。我们建立一个超级偶数源点和一个超级奇数源点,分别连接偶数点和奇数点。
对于建边操作,我们要反向建边。为什么要反向建边呢?我们反向建边后,拿超级偶数源点来说,我们跑最短路,dis[i]代表的是这个源点到i点的最短路,反过来说也就是i到超级源点的最短路。我们取奇数点记录dis[i],这样一来,就可以找到每一个奇数点离它最近的偶数点了。如果我们正向建边,dis[i]代表的是这个源点到i点的最短路,但是不能代表i点到源点的最短路。这样就不能记录dis[i]了。因此我们要反向建边,建边后跑两次最短路就可以了。
代码如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 1e9
using namespace std;const int maxx=2e6+100;
struct edge{int to;int next;
}e[maxx<<1];
int dis[maxx],vis[maxx],ans[maxx];
int a[maxx],head[maxx<<1];
int n,tot=0;inline void add(int u,int v)
{e[tot].to=v,e[tot].next=head[u],head[u]=tot++;
}
inline void spfa(int u)
{for(int i=0;i<=n+2;i++) dis[i]=inf,vis[i]=0;dis[u]=0;vis[u]=1;queue<int> q;while(q.size()) q.pop();q.push(u);while(q.size()){int v=q.front();q.pop();vis[v]=0;for(int i=head[v];i!=-1;i=e[i].next){int to=e[i].to;if(dis[to]>dis[v]+1){dis[to]=dis[v]+1;if(vis[to]==0){vis[to]=1;q.push(to);}}}}}
int main()
{scanf("%d",&n);tot=0;for(int i=1;i<=n;i++) scanf("%d",&a[i]);memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){if(i+a[i]<=n) add(i+a[i],i);if(i-a[i]>=1) add(i-a[i],i);if(a[i]%2==0) add(n+1,i);else add(n+2,i);}spfa(n+1);//偶数源点跑最短路for(int i=1;i<=n;i++) if(a[i]%2==1) ans[i]=dis[i];spfa(n+2);//奇数源点跑最短路for(int i=1;i<=n;i++) if(a[i]%2==0) ans[i]=dis[i];for(int i=1;i<=n;i++) cout<<(ans[i]==inf?-1:(ans[i]-1))<<" ";cout<<endl;return 0;
}
/*10
3 3 3 1 1 1 2 3 4 6*/

努力加油a啊,(o)/~

Nearest Opposite Parity(反向建边+spfa)相关推荐

  1. CF-346 D. Robot Control(反向建图spfa)

    CF-346 D. Robot Control(反向建图spfa) 题目链接 题意 有向图(有环)中有一个机器人,机器人有三种规则: 重复访问同一个点会自我销毁 无路可走会自我销毁 多岔路口会随机选择 ...

  2. CodeForces - 1272E Nearest Opposite Parity(多源起点的最短路)

    题目链接:点击查看 题目大意:给出 n 个点,每个点都有一个权值 a[ i ],且每个点可以到达 ( i - a[ i ] ) 和 ( i + a[ i ] ) 两个位置,花费为 1,问每个点到达与其 ...

  3. Invitation Cards POJ - 1511 SPFA(dijkstra+反向建图+邻接表(下标过大)+输入输出用stdio(iostream超时))

    题目大意: 有编号1-P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接 到达终点站,是单向的,每条路线有它自己的车费.有P个人早上从1出发 ,他们要到达每一个公交站点, 然后到了晚上再返回点 ...

  4. 解题报告:luogu P3916 图的遍历( 缩点 + DFS ? × 思维 + 反向建边 + DFS √ )

    题目链接:图的遍历 本题是一个有向图,要求每个点能到达的编号最大的点.由于是有向图,如果直接DFS如果有环就可能忽略一些点,所以我们可以直接缩点 缩点之后 在同一个强联通分量中的点可以相互到达,那么我 ...

  5. POJ-1122 FDNY to the Rescue!---Dijkstra+反向建图

    题目链接: https://vjudge.net/problem/POJ-1122 题目大意: 给出矩阵,矩阵中每个元素tij表示从第i个交叉路口到第j个交叉路口所需时间,若tij为-1则表示两交叉路 ...

  6. POJ 1511 Invitation Cards——Dijkstra优先队列优化+反向建图

    [题目描述] In the age of television, not many people attend theater performances. Antique Comedians of M ...

  7. AcWing 1132. 农场派对(最短路反向建边)

    题目链接 https://www.acwing.com/problem/content/1134/ http://poj.org/problem?id=3268 思路 我们想求所有点到x的距离以及x到 ...

  8. AcWing 4246. 最短路径和(反向建图+链式前向星+堆优化)

    题目连接 https://www.acwing.com/problem/content/description/4249/ http://poj.org/problem?id=1511 思路 其实这道 ...

  9. cf1693C. Keshi in Search of AmShZ(div1)【最短路,反向建图】

    传送门 题意 在一个有向图上需要从点 111 到点 nnn,每次可以选择以下一种操作: 1.删除一条边 2.随机移动到当前点能够通向的另一点 求所需操作次数到达终点的最大值的最小值 看到求最大值的最小 ...

最新文章

  1. 堆(heap)与栈(stack)的区别(一)
  2. 如何给安卓应用添加权限
  3. python学哪个版本-老男孩python学习用的哪个版本?
  4. 跨域 (3) window.name
  5. Spring 杂谈.
  6. 面试问:Kafka为什么速度那么快?
  7. 熔断器 Hystrix 的原理与使用
  8. 手把手教你理解卷积神经网络
  9. 前端详细设计文档怎么写_UI设计师简历应该怎么写?
  10. 算法导论2nd 10.1-7
  11. 元组中[-1]的作用
  12. Jquery学习总结(6)——JQuery万能代码段
  13. Dart教程(四):语法
  14. ffmpeg 处理字幕
  15. python趋势跟踪_一个趋势跟踪系统—Dual Thrust策略(期货)
  16. 再看《西游记》——吴承恩眼中的现实社会是如何折射到《西游记》中的
  17. 升级 | 联想Y430p更换SSD、增加8G内存条
  18. Hibit Uninstall 批量的软件卸载,强制卸载
  19. 反函数的导数——arcsinx的导数求导证明
  20. git常用操作以及码云Gitee连接git

热门文章

  1. 计算机组成原理,P函数,深入浅出计算机组成原理学习笔记:第五讲
  2. android悬浮窗代码布局,三行代码实现Android应用内悬浮窗,无需一切权限,适配所有ROM和厂商...
  3. c语言用数组实现栈的插入,用数组实现栈的功能的C语言代码?
  4. 外服封号_外服大主播Diss原神:因为吐槽氪金体验差,米哈游把我号封了
  5. 幅度和幅值有区别吗_克拉克 (Clark) 变换中等幅值 (2/3) 和等功率 (sqrt(2/3)) 变换的公式推导...
  6. 打包指令_将Vue项目打包为Windows应用(.exe)
  7. iOS中常用的四种数据持久化方法
  8. SpringBoot环境下QueryDSL-JPA的使用
  9. poj1942(求组合数)
  10. V神:区块链跨链技术大规模应用将在一到两年内爆发