CF721C Journey (dp+拓扑)

典型的拓扑序来求最小花费

然后满足花费的判断最大值

存路径一般都是用一个数组来存,老套路了

拓扑在DAG上真的好用

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define ull unsigned long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e5+10;
int in[N];
int n,m,t;
vector<pll> g[N];
int f[5010][5010];
int pre[5010][5010];
vector<int> num;
void topo(){
    queue<int> q;
    int i;
    memset(f,0x3f,sizeof f);
    f[1][1]=0;
    for(i=1;i<=n;i++){
        if(!in[i])
            q.push(i);
    }
    while(q.size()){
        int t=q.front();
        q.pop();
        for(i=0;i<g[t].size();i++){
            int s=g[t][i].first;
            int tmp=g[t][i].second;
            in[s]--;
            for(int j=2;j<=n;j++){
                if(f[s][j]>f[t][j-1]+tmp){
                    f[s][j]=f[t][j-1]+tmp;
                    pre[s][j]=t;
                }
            }
            if(!in[s])
                q.push(s);
        }
    }
}
int main(){
    cin>>n>>m>>t;
    int i;
    for(i=1;i<=m;i++){
        int u,v,c;
        scanf("%d%d%d",&u,&v,&c);
        g[u].push_back(pll{v,c});
        in[v]++;
    }
    topo();
    int res=-1;
    int id=-1;
    for(i=1;i<=n;i++){
        if(f[n][i]<=t)
            res=max(res,i);
    }
    cout<<res<<endl;
    int now=n;
    while(res){
        num.push_back(now);
        now=pre[now][res];
        res--;
    }
    for(i=(int)num.size()-1;i>=0;i--){
        printf("%d ",num[i]);
    }
    cout<<endl;
    return 0;
}
View Code

 

posted @ 2020-04-04 20:28  朝暮不思  阅读(233)  评论(0编辑  收藏  举报