Power OJ 2605 SPFA+dp思想
Posted Pealicx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Power OJ 2605 SPFA+dp思想相关的知识,希望对你有一定的参考价值。
题目链接【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思想的主要内容,如果未能解决你的问题,请参考以下文章