Codeforce 721C(DAG上dp)

来源:互联网 发布:阿里云邮箱登录名忘记 编辑:程序博客网 时间:2024/05/17 07:46

链接:点击打开链接

题意:N个点M条的有向无环图,问从1走到n花费时间不超过T最多能经过多少个城市

代码:

#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;struct node{    int to,cost;};vector<node> G[5005];int n,m,T;int vis[5005];int dp[5005][5005],nex[5005][5005];void dfs(int s){                                //dp[i][j]表示在第i点经过j个点到n点的最小距离    int i,j,tmp;    if(vis[s])                                  //每个点只能进过一次,只有这样复杂度才是O(n)    return;    vis[s]=1;    for(i=0;i<G[s].size();i++){        tmp=G[s][i].to;        dfs(tmp);        for(j=2;j<=n;j++){                      //从后向前dp,也可以从前向后用拓扑加dp            if(dp[tmp][j-1]+G[s][i].cost<dp[s][j]){                dp[s][j]=dp[tmp][j-1]+G[s][i].cost;                nex[s][j]=tmp;            }        }    }}int main(){    int i,j,u,v,w,st,ans;    while(scanf("%d%d%d",&n,&m,&T)!=EOF){        for(i=1;i<=n;i++)        G[i].clear();        for(i=1;i<=m;i++){            scanf("%d%d%d",&u,&v,&w);            if(v==1||u==n)                      //因为是从1点走向n点,所以到1和出n的都没有用            continue;            G[u].push_back((node){v,w});        }        memset(dp,INF,sizeof(dp));        memset(vis,0,sizeof(vis));        vis[n]=1,dp[n][1]=0;        dfs(1);        for(i=n;;i--){            if(dp[1][i]<=T){                ans=i;                break;            }        }        printf("%d\n",ans);        st=1;        printf("%d",st);        while(st!=n){            st=nex[st][ans--];            printf(" %d",st);        }        printf("\n");    }    return 0;}

0 0
原创粉丝点击