CF #374 (Div. 2) C. Journey dp
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\n",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; }