Power OJ 2605 SPFA+dp思想
阿新 • • 發佈:2017-10-06
power cond clas pre include logs true spfa 情況
題目鏈接【https://www.oj.swust.edu.cn/problem/show/2605】
題意:給出包含N(N <= 5000)個點M條邊的有向圖,然後求1 - N在滿足距離小於T的情況下,最多走多少個點。
題解:dp[i][j]表示鄒大鵬i點,經過了j個點的最短路。用pre維護一下路徑即可。
#include<bits/stdc++.h> using namespace std; typedef pair<int, int> Pair; const int INF = 1e9 + 15; const int maxn = 5050; int N, M, T; struct Edge { int to, next, len; Edge() {} Edge(int to, int next, int len): to(to), next(next), len(len) {} } E[maxn*maxn]; int head[maxn], tot; void initEdge() { for(int i = 0; i <= N; i++) head[i] = -1; tot = 0; } void addEdge(int u, int v, int len) { E[tot] = Edge(v, head[u], len); head[u] = tot++; } int dp[maxn][maxn], pre[maxn][maxn], in[maxn][maxn]; void Spfa() { queue<Pair>que; dp[1][1] = 0; que.push(make_pair(1, 1)); in[1][1] = 1; while(!que.empty()) { int u = que.front().first; int num = que.front().second; que.pop(); in[u][num] = 0; for(int k = head[u]; ~k; k = E[k].next) { int v = E[k].to; if(dp[v][num + 1] > dp[u][num] + E[k].len) { dp[v][num + 1] = dp[u][num] + E[k].len; pre[v][num + 1] = u; if(!in[v][num + 1]) { que.push(make_pair(v, num + 1)); in[v][num + 1] = 1; } } } } } int main () { while(~scanf("%d %d %d", &N, &M, &T)) { initEdge(); for(int i = 1; i <= M; i++) { int u, v, len; scanf("%d %d %d", &u, &v, &len); addEdge(u, v, len); } for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) dp[i][j] = INF, pre[i][j] = in[i][j] = 0; Spfa(); int ans = N; for(; ans >= 1; ans--) if(dp[N][ans] <= T) break; vector<int>vt; int u = N, num = ans; while(pre[u][num]) { int v = pre[u][num]; vt.push_back(v); u = v; num--; } printf("%d\n%d\n", dp[N][ans], ans); int sz = vt.size() - 1; for(int i = sz; i >= 0; i--) printf("%d ", vt[i]); printf("%d\n", N); } return 0; }
Power OJ 2605 SPFA+dp思想