当前位置:   article > 正文

Nearest Opposite Parity (CodeForces - 1272E)(超级源点+反向建边+dijkstra)_codeforce 图论 超级源点 超级汇点

codeforce 图论 超级源点 超级汇点

Description

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 

解析:

首先我们添加两个超级源点,将多源最短路转化为单元最短路,并且反向建边。

我们假设超级源点0连接所有的偶点,然后进行一次dijkstra算法求出超级源点0到所有点的最短距离。

假设某个最短路上有一奇点v,那么dis[v]就是对应的答案,因为超级源点0连接的是所有的偶数点,并且是反向建边。

AC代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int INF = 1 << 30;
  4. const int maxn = 2e5 + 5;
  5. int n, a[maxn];
  6. vector<pair<int, int> >edge[maxn];
  7. int dis[maxn], ans[maxn];
  8. bool vis[maxn];
  9. struct cmp
  10. {
  11. bool operator () (const pair<int, int> &lhs, const pair<int, int> &rhs)
  12. {
  13. return lhs.second > rhs.second;
  14. }
  15. };
  16. void dijkstra(int dir)
  17. {
  18. for(int i = 0; i < n + 2; i++)
  19. dis[i] = INF, vis[i] = false;
  20. priority_queue<pair<int, int>, vector<pair<int, int> >, cmp> que;
  21. que.push(make_pair(dir, 0));
  22. dis[dir] = 0;
  23. while(!que.empty())
  24. {
  25. pair<int, int> u = que.top();
  26. que.pop();
  27. if(vis[u.first])
  28. continue;
  29. vis[u.first] = true;
  30. for(int i = 0; i < edge[u.first].size(); i++)
  31. {
  32. int v = edge[u.first][i].first;
  33. if(vis[v])
  34. continue;
  35. if(dis[v] > dis[u.first] + edge[u.first][i].second)
  36. {
  37. dis[v] = dis[u.first] + edge[u.first][i].second;
  38. que.push(make_pair(v, dis[v]));
  39. }
  40. }
  41. }
  42. }
  43. int main()
  44. {
  45. scanf("%d", &n);
  46. for(int i = 1; i <= n; i++)
  47. {
  48. scanf("%d", &a[i]);
  49. if(a[i] + i <= n)
  50. edge[i + a[i]].push_back(make_pair(i, 1));
  51. if(i - a[i] >= 1)
  52. edge[i - a[i]].push_back(make_pair(i, 1));
  53. }
  54. for(int i = 1; i <= n; i++)
  55. {
  56. if(a[i] & 1)
  57. edge[n + 1].push_back(make_pair(i, 0));
  58. else
  59. edge[0].push_back(make_pair(i, 0));
  60. ans[i] = -1;
  61. }
  62. dijkstra(0);
  63. for(int i = 1; i <= n; i++)
  64. if(a[i] % 2 == 1 && dis[i] != INF)
  65. ans[i] = dis[i];
  66. dijkstra(n + 1);
  67. for(int i = 1; i <= n; i++)
  68. if(a[i] % 2 == 0 && dis[i] != INF)
  69. ans[i] = dis[i];
  70. for(int i = 1; i <= n; i++)
  71. printf("%s%d", i == 1 ? "" : " ", ans[i]);
  72. return 0;
  73. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/745271
推荐阅读
相关标签
  

闽ICP备14008679号