CF #374 (Div. 2) C. Journey dp

1、CF #374 (Div. 2)    C.  Journey   

2、总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍。。

3、题意:有向无环图,找出第1个点到第n个点的一条路径,经过的点数要最多。

#include<bits/stdc++.h>
#define F(i,a,b) for (int i=a;i<b;i++)
#define FF(i,a,b) for (int i=a;i<=b;i++)
#define mes(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=5100,MAX=1000100;

int n,m,T,dp[N][N],pre[N][N];   //dp[i][j]表示走过j个点到达第i个点的时间,pre记录父亲路径
int w[N],head[N],from[N],to[N],nexte[N];

void AddEdge(int u,int v,int t,int e)
{
    from[e]=u;
    to[e]=v;
    nexte[e]=head[u];
    head[u]=e;
    w[e]=t;
}

void PrintPath()
{
    int num;
    FF(i,1,n){
        if(dp[n][i]<=T)num=i;
    }printf("%d
",num);

    stack<int >S;
    int k=n;
    for(int i=num;i>0;i--){
        S.push(k);
        k=pre[k][i];
    }
    printf("%d",S.top());S.pop();
    while(!S.empty()){
        printf(" %d",S.top());
        S.pop();
    }puts("");

}

void Solve()
{
    mes(dp,INF);
    dp[1][1]=0;
    FF(i,2,n){      //直接双层循环搞出dp[][]的值
        FF(j,1,m){
            int u=from[j],v=to[j],val=w[j];
            if(dp[u][i-1]+val<=T&&dp[u][i-1]+val<dp[v][i]){
                dp[v][i]=dp[u][i-1]+val;
                pre[v][i]=u;
            }
        }
    }

    PrintPath();
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&T))
    {
        mes(w,INF);
        mes(head,-1);
        int u,v,t;
        FF(i,1,m){
            scanf("%d%d%d",&u,&v,&t);
            AddEdge(u,v,t,i);
        }
        Solve();

    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/sbfhy/p/5927387.html