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; }
没有人不辛苦,只有人不喊疼