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
%d
", dp[N][ans], ans);
        int sz = vt.size() - 1;
        for(int i = sz; i >= 0; i--)
            printf("%d ", vt[i]);
        printf("%d
", N);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/pealicx/p/7631322.html