Codeforces #374 div2 C Dp

来源:互联网 发布:java 写成绩划分 编辑:程序博客网 时间:2024/06/05 23:55

题目链接

题意


从1到n的路径中,时间不能超过T, 经过的点的最多的路径输出。


解析


用DP(动态规划), dp[i][u]中表示经过i个点到节点u的时间。若存在<u,v>边,则转移方程为dp[i][v]=dp[i1][u]+cost,初始化dp[1][1]=0。


代码

#include<iostream>  #include<cstdio>  #include<ctime>  #include<cstring>  #include<cstdlib>  #include<vector> #include <algorithm>#include <queue>const int maxn = 5000+10;using namespace std;  typedef long long LL;using namespace std;const int inf = 0x3f3f3f3f;typedef pair<int, int> P;int dp[maxn][maxn];int path[maxn][maxn];vector<int>ans;vector<P>g[maxn];int main() {    int n, m , T;    scanf("%d%d%d", &n, &m, &T);    for (int i=0; i<m; i++) {        int u, v, w;        scanf("%d%d%d", &u, &v, &w);        g[u].push_back(make_pair(v, w));    }    memset(dp, inf, sizeof(dp));    dp[1][1] = 0;    memset(path, -1, sizeof(path));    for (int i=2; i<=n; i++) {        for (int j=1; j<=n; j++) {            for (int k=0; k<g[j].size(); k++) {                int v = g[j][k].first;                int w = g[j][k].second;                if (dp[i][v] >= dp[i-1][j]+w) {                    path[i][v] = j;                    dp[i][v] = dp[i-1][j]+w;                }            }        }    }    int num;    for (int i=1; i<=n; i++)        if (dp[i][n] <= T)            num = i;    int t = num;    for (int fa = n; fa!=-1; fa=path[t--][fa])        ans.push_back(fa);    cout<<num<<endl;    for (int i=(int)ans.size()-1; i>=0; i--)        printf("%d ", ans[i]);    printf("\n");    return 0;}
0 0
原创粉丝点击