CodeForces-721C-Journey(DAG, DP)

链接:

https://vjudge.net/problem/CodeForces-721C

题意:

Recently Irina arrived to one of the most famous cities of Berland — the Berlatov city. There are n showplaces in the city, numbered from 1 to n, and some of them are connected by one-directional roads. The roads in Berlatov are designed in a way such that there are no cyclic routes between showplaces.

Initially Irina stands at the showplace 1, and the endpoint of her journey is the showplace n. Naturally, Irina wants to visit as much showplaces as she can during her journey. However, Irina's stay in Berlatov is limited and she can't be there for more than T time units.

Help Irina determine how many showplaces she may visit during her journey from showplace 1 to showplace n within a time not exceeding T. It is guaranteed that there is at least one route from showplace 1 to showplace n such that Irina will spend no more than T time units passing it.

思路:

Dp[i][j] 为i点到n点经过j个点的时间.可以在图上得到方程Dp[i][j] = min(dp[k][j-1]+dis(i,k)).

代码:

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 5e3+10;

struct Edge
{
    int to, dis;
};
vector<Edge> G[MAXN];
bool Vis[MAXN];
int To[MAXN][MAXN], Dp[MAXN][MAXN];
int n, m, t;

void Dfs(int x)
{
    Vis[x] = true;
    if (x == n)
        return;
    for (int i = 0;i < G[x].size();i++)
    {
        int v = G[x][i].to;
        int dis = G[x][i].dis;
        if (!Vis[v])
            Dfs(v);
        for (int j = 2;j <= n;j++)
        {
            if (Dp[v][j-1]+dis < Dp[x][j])
            {
                Dp[x][j] = Dp[v][j-1]+dis;
                To[x][j] = v;
            }
        }
    }
}

int main()
{
    memset(Dp, 0x3f3f3f3f, sizeof(Dp));
    scanf("%d %d %d\n", &n, &m, &t);
    int u, v, w;
    for (int i = 1;i <= m;i++)
    {
        scanf("%d %d %d", &u, &v, &w);
        G[u].push_back(Edge{v, w});
    }
    Dp[n][1] = 0;
    Dfs(1);
    int maxp = 1;
    for (int i = n;i >= 1;i--)
    {
        if (Dp[1][i] <= t)
        {
            maxp = i;
            break;
        }
    }
    printf("%d\n", maxp);
    int p = 1, x = maxp;
    printf("1");
    while (x > 1)
    {
        printf(" %d", To[p][x]);
        p = To[p][x--];
    }
    puts("");

    return 0;
}

转载于:https://www.cnblogs.com/YDDDD/p/11385440.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值