题目链接:http://codeforces.com/contest/721/problem/C
题意:从1走到n,问在时间T内最多经过多少个点,按路径顺序输出。
思路:比赛的时候只想到拓排然后就不知道怎么办了......先拓扑排序,再按照拓扑的顺序进行DP,dp[to][j](到i点走过j个点最短时间) = min(dp[to][j], dp[i][j] + dis)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 5e3 + 3; const int inf = 0x3f3f3f3f; struct node { int to; int dis; node() {} node(int a,int b) : to(a), dis(b) {} }; vector <node> G[N]; queue<int> q; int dp[N][N],pre[N][N],ans[N],deg[N]; int main() { int n,m,t,num; scanf("%d %d %d",&n,&m,&t); memset(dp,inf,sizeof(dp)); for(int i = 1; i <= m; i++) { int u,v,d; scanf("%d %d %d",&u,&v,&d); G[u].push_back(node(v,d)); deg[v]++; } dp[1][1] = 0; for(int i = 1; i <= n; i++) { if(!deg[i]) q.push(i); } while(!q.empty()) { int i = q.front(); q.pop(); for(int j = 0; j < G[i].size(); j++) { node tmp = G[i][j]; if(!--deg[tmp.to]) q.push(tmp.to); for(int k = 2; k <= n; k++) { if(dp[i][k-1] + tmp.dis < dp[tmp.to][k]) { dp[tmp.to][k] = dp[i][k-1] + tmp.dis; pre[tmp.to][k] = i; } } } } for(int i = n; i >= 1; i--) { if(dp[n][i] <= t) { num = i; break; } } ans[num] = n; for(int i = n,j = num; j > 1; i = pre[i][j], j--) ans[j-1] = pre[i][j]; printf("%d ",num); for(int i = 1; i <= num; i++) printf("%d ",ans[i]); return 0; }