CSES - Longest Fight Route (最长路径)
题意
求从节点$1$到节点$n$的最长路径长度。
题解
这是有向无环图求最长路径问题, 运用DP思想使用拓扑排序消除后效性,
定义状态:$dp[i]$表示从节点$1$到节点$i$的最长路径长度。
状态转移:
$$dp[i] = \max_{j \in adj[i]} dp[j] + 1$$
其中$dp[i]$要确保所有到$i$节点的路径都已经计算出来了, 这就需要用到拓扑排序, 把每个节点的所有前驱节点都计算出来才能计算
参考代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <climits> #include <queue> #pragma GCC optimize("Ofast") #include<bits/stdc++.h> using namespace std; #define i128 __int128
#ifdef DEBUG #define de(x) cout << (#x) << " = " << (x) << endl; #define de2(x, y) cout << (#x) << " , " << (#y) << " = " << (x) << " ~ " << (y) << endl; #else #define de(x) #define de2(x, y) #endif
#define enld endl #define endl '\n' #define fi(x) for(int i = 1; i <= x; ++i) #define fi0(x) for(int i = 0; i < x; ++i) #define fj(n) for(int j = 1; j <= n; ++j) #define caillo ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define PLEASE_AC return 0 typedef long long ll; #define int long long
const int N = 1e5 + 10; int n, m;
int dp[N], pre[N]; vector<int> adj[N]; int ind[N];
void bfs(){ for(int i = 0;i <= n; ++i) dp[i] = -INT_MAX; queue<int> q; for(int i = 1;i <= n; ++i) if(!ind[i]) q.push(i); pre[1] = 0; dp[1] = 1;
while(!q.empty()) { int d = q.front(); q.pop();
for(auto c : adj[d]) { ind[c]--; if(dp[d] > 0) { if(dp[c] < dp[d] + 1) { dp[c] = dp[d] + 1; pre[c] = d; } } if(!ind[c]) q.push(c); } } }
void printl(){ if(dp[n] < 1) cout << "IMPOSSIBLE\n"; else { cout << dp[n] << endl; vector<int> ans; int x = n; while(x != 0){ ans.push_back(x); x = pre[x]; } reverse(ans.begin(), ans.end()); for(auto c : ans) cout << c << ' '; } }
signed main() { caillo; cin >> n>> m; fi(m) { int u, v; cin >> u >> v; adj[u].push_back(v); ind[v]++; }
bfs(); printl(); }
|