标签:problem color while als with site click tps front
题目链接:https://codeforces.ml/contest/1272/problem/E
题意:给定数组 a1 a2 an 每个数可以从当前的i 跳到i+a[i] 或者i-a[i] (不能越界) 问每个数最少跳多少次能跳到一个奇偶性与当前的a[i]不同的位置上
思路: 刚开始的想法是记忆化搜索 每一个数都dfs一下 然后已经记录下的数就能用了 但是因为有环 记忆化搜索很难处理环 所以行不通
那么考虑这是多源最短路 想到dijistra 边权为1 =bfs 然后要处理成 判断ans[v]>ans[u]+1 这种形式 所以反向建图
从ans[i]=1 的点开始bfs 这样就不用考虑环的问题 如果环中的数奇偶性相同,那么我们不会跑到这个环中,如果不同,我们肯定会从哪个为1的点开始跑完而不会死循环
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define pb push_back 6 const int maxn=2e5+10; 7 const int mod=1e9+7; 8 int n; 9 int a[maxn]; 10 int ans[maxn]; 11 vector<int>E[maxn]; 12 13 14 15 int main() 16 { 17 ios::sync_with_stdio(false); 18 cin.tie(0); 19 cin>>n; 20 for(int i=1;i<=n;i++) 21 ans[i]=1e9; 22 for(int i=1;i<=n;i++) 23 cin>>a[i]; 24 for(int i=1;i<=n;i++) 25 { 26 if(i+a[i]<=n&&a[i]%2!=a[i+a[i]]%2) 27 ans[i]=1; 28 if(i-a[i]>=1&&a[i]%2!=a[i-a[i]]%2) 29 ans[i]=1; 30 } 31 32 for(int i=1;i<=n;i++) 33 { 34 if(i+a[i]<=n) 35 { 36 E[i+a[i]].pb(i); 37 } 38 if(i-a[i]>=1) 39 { 40 E[i-a[i]].pb(i); 41 } 42 } 43 queue<int>q; 44 for(int i=1;i<=n;i++) 45 if(ans[i]==1) 46 q.push(i); 47 48 while(!q.empty()) 49 { 50 int u=q.front(); 51 q.pop(); 52 for(auto &v:E[u]) 53 { 54 if(ans[v]>ans[u]+1) 55 { 56 ans[v]=ans[u]+1; 57 q.push(v); 58 } 59 } 60 } 61 for(int i=1;i<=n;i++) 62 { 63 if(ans[i]==1e9) 64 ans[i]=-1; 65 } 66 for(int i=1;i<=n;i++) 67 cout<<ans[i]<<" "; 68 69 70 71 72 73 74 75 }
Codeforces Round #605 (Div. 3) E. Nearest Opposite Parity
标签:problem color while als with site click tps front
原文地址:https://www.cnblogs.com/winfor/p/13247002.html