Codeforces 346D Robot Control DP spfa 01BFS
题意及思路:https://www.cnblogs.com/zjp-shadow/p/9562888.html
这题由于性质特殊,可以用01BFS来进行DP的转移。
代码:
#include <bits/stdc++.h> using namespace std; const int maxn = 1000010; vector<int> G[maxn]; deque<int> q; int dp[maxn], deg[maxn]; bool v[maxn]; void add(int x, int y) { G[x].push_back(y); deg[y]++; } void bfs(int s, int t) { memset(dp, -1, sizeof(dp)); dp[s] = 0; q.push_back(s); while(q.size()) { int x = q.front(); q.pop_front(); if(v[x]) continue; v[x] = 1; //if(x == t) return; for (auto y : G[x]) { if(!--deg[y]) { if(dp[y] > dp[x] || dp[y] == -1) { dp[y] = dp[x]; q.push_front(y); } } else if(dp[y] == -1) { dp[y] = dp[x] + 1; q.push_back(y); } } } } int main() { int n, m, x, y, s, t; scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%d%d", &x, &y); add(y, x); } scanf("%d%d", &s, &t); bfs(t, s); printf("%d\n", dp[s]); }
但是实际上,遇到有后效性的DP方程时,如果是一个DAG,一般用spfa来进行DP的状态转移,因为spfa是迭代的思想,如果所有状态都收敛了(不能更新了),就完成了转移。
思路来源:https://www.cnblogs.com/huibixiaoxing/p/7715898.html
代码:
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; const int maxn = 1000010; vector<int> G[maxn], G1[maxn]; int dp[maxn]; bool v[maxn]; void add(int x, int y) { G[x].push_back(y); G1[y].push_back(x); } queue<int> q; void spfa(int s, int t) { memset(dp, 0x3f, sizeof(dp)); dp[s] = 0; v[s] = 1; q.push(s); while(q.size()) { int x = q.front(); q.pop(); v[x] = 0; for (auto y : G[x]) { if(dp[y] > dp[x] + 1) { dp[y] = dp[x] + 1; if(!v[y]) { q.push(y); v[y] = 1; } } } int tmp = 0; for (auto y : G1[x]) { tmp = max(tmp, dp[y]); } if(dp[x] > tmp) { dp[x] = tmp; if(!v[x]) { q.push(x); v[x] = 1; } } } } int main() { int n, m, x, y, s, t; scanf("%d%d", &n, &m); for (int i = 1; i <= m; i++) { scanf("%d%d", &x, &y); add(y, x); } scanf("%d%d", &s, &t); spfa(t, s); if(dp[s] == INF) dp[s] = -1; printf("%d\n", dp[s]); }