CF374/C(动态规划)

这里写图片描述
这里写图片描述

题目看上去感觉像是dijstra,但是不是最短路,而是在实践允许的范围内选择最多的点去走完从1到n的路,这个想到的是动态规划,以边为核心,一条边一条边的扫过,如果这条边对应的起点和终点连接上之后,对于从1到终点来说是有利的就加上那种,我还不是很理解,只是把标程看懂自己敲了一遍而已。

#include<iostream>
using namespace std;
#include<stack>
const int inf = 0x3f3f3f;//特别大的数,记下来
const int maxn = 5005;

int dp[maxn][maxn], pre[maxn][maxn];
//dp[i][j]表示经过i个点,从1到j,其中点的个数包括j

struct edge
{
    int u, v, w;
}eg[maxn];

int n, m, t;

stack<int>reu;

int main()
{
    while (cin >> n >> m >> t)
    {
        memset(dp, inf, sizeof(dp));
        memset(pre, -1, sizeof(pre));
        int i;
        for (i = 0; i < m; i++)
            cin >> eg[i].u >> eg[i].v >> eg[i].w;
        int j;
        int pos;
        dp[1][1] = 0;//从1到1必然是0
        for (i = 2; i <= n; i++)//从2开始循环,到n个点
        {
            for (j = 0; j < m; j++)//扫过每条边
            {
                int u = eg[j].u;
                int v = eg[j].v;
                int w = eg[j].w;
                if (dp[i - 1][u] + w < dp[i][v])//关键的动态规划的过程
                {
                    dp[i][v] = dp[i - 1][u] + w;
                    pre[i][v] = u;//表示经过i个点到达v之后,前一个点是u
                }
            }
            if (dp[i][n] <= t)
                pos = i;//更新一次答案
        }
        cout << pos << endl;
        int ans = n;
        while (ans != -1)
        {
            reu.push(ans);
            ans = pre[pos--][ans];//所以pre是一个用来记录路线的数组
        }
        while (!reu.empty())
        {
            cout << reu.top() << " ";
            reu.pop();
        }
        cout << endl;
    }
    return 0;
}

希望日后可以对dp有更深的理解!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值