【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)

C. Journey
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.

Input
The first line of the input contains three integers n, m and T (2 ≤ n ≤ 5000,  1 ≤ m ≤ 5000,  1 ≤ T ≤ 109) — the number of showplaces, the number of roads between them and the time of Irina‘s stay in Berlatov respectively.

The next m lines describes roads in Berlatov. i-th of them contains 3 integers ui, vi, ti (1 ≤ ui, vi ≤ n, ui ≠ vi, 1 ≤ ti ≤ 109), meaning that there is a road starting from showplace ui and leading to showplace vi, and Irina spends ti time units to pass it. It is guaranteed that the roads do not form cyclic routes.

It is guaranteed, that there is at most one road between each pair of showplaces.

Output
Print the single integer k (2 ≤ k ≤ n) — the maximum number of showplaces that Irina can visit during her journey from showplace 1 to showplace n within time not exceeding T, in the first line.

Print k distinct integers in the second line — indices of showplaces that Irina will visit on her route, in the order of encountering them.

If there are multiple answers, print any of them.

Examples
input
4 3 13
1 2 5
2 3 7
2 4 8
output
3
1 2 4
input
6 6 7
1 2 2
1 3 3
3 6 3
2 4 2
4 6 2
6 5 1
output
4
1 2 4 6
input
5 5 6
1 3 3
3 5 3
1 2 2
2 4 3
4 5 2
output
3
1 3 5 

  一道图论题,DFS t了,BFS MLE了。看来最优解应该是DP没跑了。

  下面尝试定义转移方程: dp[i][j]表示在经过了i个城市之后到达编号为j的城市所消耗的最小时间。

  转移方程写得好,一切问题就变的简单了。反观这题,题中一共三个变量,经历城市数(希望最大化),消耗的时间(希望最小化),当前城市编号(希望到达n)。

  为了达到上述目的,我们只需要在dp[i][n]<=T中找最大的i就好了, 另外开辟一个parent[i][j]:表示经历了i 个点后从parent[i][j]到达了j点。

IF u can reach v
    dp[i][v] = min(dp[i][v], dp[i - 1][u] + w(u, v));

  最后就是转移方程的第一维度可以从1->n枚举,第二维我们可以通过遍历整个边集合,来找到每一个u->v来更新当前经历过i个点下的dp[i][v]。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>

using namespace std;

const int Maxn = 5005;

int cntE, head[Maxn];
int n, m, T;

typedef struct Node{
    int from, to, next, w;
}Edge;
Edge edges[Maxn];

void init()
{
    memset(head, -1, sizeof head);
    cntE = 0;
}
void addEdge(int u, int v, int w)
{
    edges[cntE].from = u;
    edges[cntE].to = v;
    edges[cntE].w = w;
    edges[cntE].next = head[u];
    head[u] = cntE ++;
}
int parent[Maxn][Maxn], dp[Maxn][Maxn];

void printPath(int pos)
{
    printf("%d\n", pos);
    int id = n;
    vector<int>ans;
    ans.push_back(id);
    for(int i = pos; i > 1 ; i --){
        ans.push_back(parent[i][id]);
        id = parent[i][id];
    }
    printf("%d",ans[ans.size() - 1]);
    for(int i = ans.size() - 2; i >= 0; i --){
        printf(" %d",ans[i]);
    }cout<<endl;
}
void solveByDp()
{
    for(int i = 0; i < n + 1; i ++){
        for(int j = 0; j < n + 1; j ++){
            dp[i][j] = T + 1;
        }
    }
    dp[1][1] = 0;
    //经历了i个点
    int u, v, w, pos = 1;
    for(int i = 2; i <= n; i ++){
        //到达j点
        for(int j = 0; j < m; j ++){
            u = edges[j].from, v = edges[j].to, w = edges[j].w;
            if(dp[i - 1][u] + w < dp[i][v]){
                dp[i][v] = dp[i - 1][u] + w;
                parent[i][v] = u;
            }
        }
        if(dp[i][n] <= T){
            pos = i;
        }
    }
    printPath(pos);
}

int main()
{
    init();
    int u, v, w;
    cin>>n>>m>>T;
    for(int i = 0; i < m; i ++){
        scanf("%d%d%d", &u, &v, &w);
        addEdge(u, v, w);
    }
    solveByDp();
    return 0;
}

  

时间: 2024-08-24 07:00:29

【Codeforces】Codeforces Round #374 (Div. 2) -- C. Journey (DP)的相关文章

Codeforces Round #260 (Div. 1) A. Boredom (DP)

题目链接:http://codeforces.com/problemset/problem/455/A A. Boredom time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Alex doesn't like boredom. That's why whenever he gets bored, he comes up with

【cf1293E】E.Xenon&#39;s Attack on the Gangs(dp)

传送门 题意: 给出一颗树,树上随机分配\(0\)到\(n-1\)的边权,不存在权值相同的两条边. 定义\(mex(u,v)\)为:树上\(u\)到\(v\)的简单路径中所有边权的\(mex\). 求 \[ \sum_{1\leq u\leq v\leq n}mex(u,v) \] 思路: 将问题转化为求一条边的贡献,显然一条边对跨过这条边的所有点对有贡献: 多条边时,只有链的形式才会增加贡献,可以不用考虑具体的权值分配: 因为数据范围只有\(3000\),考虑枚举每条链进行\(dp\). 记忆

Codeforces Round #247 (Div. 2) C. k-Tree (dp)

题目链接 题意: 思路: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 const int mo = 1000000000 + 7; 8 int dp[110][110][110]; 9 10 int main() 11 { 12

Codeforces Round #262 (Div. 2) 460C. Present(二分)

题目链接:http://codeforces.com/problemset/problem/460/C C. Present time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little beaver is a beginner programmer, so informatics is his favorite subjec

【HDOJ 5653】 Bomber Man wants to bomb an Array.(DP)

[HDOJ 5653] Bomber Man wants to bomb an Array.(DP) Bomber Man wants to bomb an Array. Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 389    Accepted Submission(s): 117 Problem Description Give

【LaTeX】E喵的LaTeX新手入门教程(2)基础排版

换了块硬盘折腾了好久..联想的驱动真坑爹.前情回顾[LaTeX]E喵的LaTeX新手入门教程(1)准备篇文档框架嗯昨天我们已经编写了一个最基本的文档,其内容是这样的:\documentclass{article}\begin{document}XXX is a SB.\end{document}这个文档呢其实是分为两部分的:一部分是\begin{document}之前的那部分也就是第一行,这一部分我们称之为导言区.导言区的内容可以不只一行,它的作用是完成文档的基础设定.比如在这个文档中,我们使用

【LaTeX】E喵的LaTeX新手入门教程(5)参考文献、文档组织

这不是最后一篇,明天开始建模所以会从6号开始继续更新.前情回顾[LaTeX]E喵的LaTeX新手入门教程(1)准备篇 [LaTeX]E喵的LaTeX新手入门教程(2)基础排版 [LaTeX]E喵的LaTeX新手入门教程(3)数学公式 [LaTeX]E喵的LaTeX新手入门教程(4)图表参考文献天下文章一大抄,抄来抄去有提高. ——白岩松常备工具:JabRef>>戳我下载<<JabRef是一款管理参考文献用的软件,相当好用.装好了以后在选项中把这两个选项改成如图示的样子.*nix用户

【LaTeX】E喵的LaTeX新手入门教程(3)数学公式

昨天熄灯了真是坑爹.前情回顾[LaTeX]E喵的LaTeX新手入门教程(1)准备篇 [LaTeX]E喵的LaTeX新手入门教程(2)基础排版上一期测试答案1.大家一开始想到的肯定是\LaTeX{}er.其实\LaTeX er也可以的.2.\LaTeX{} er或\LaTeX\ er数学模式现在我们打算在文档中插入一些数学公式什么的了:按照正常的情况来说,数学公式里面的字符一般都是斜体,而我们要用\textit来一点点把需要变的文字变成斜体这显然是一件极其坑爹的事情.TeX的创造者高爷爷表示他搞T

【LaTeX】E喵的LaTeX新手入门教程(4)图表

这里说的不是用LaTeX画图,而是插入已经画好的图片..想看画图可以把滚动条拉到底.前情回顾[LaTeX]E喵的LaTeX新手入门教程(1)准备篇 [LaTeX]E喵的LaTeX新手入门教程(2)基础排版 [LaTeX]E喵的LaTeX新手入门教程(3)数学公式图片的插入A picture says more than a thousand words. — Shakespeare没图你说个××. ——莎士比亚LaTeX支持的图片格式由于在前面的教程中建议大家使用XeLaTeX,因此在图形格式的