原题链接:点击打开链接
题意:一个n个节点的有向图,m条边,每条边上都有需要花费的时间,问在T时间内最多能走几个节点,并输出相应节点。
直接建图跑dp
dp[i][j]表示在第i个节点时已经走过j个节点数时所花最小时间。
状态转移方程:dp[i][j]=min(dp[k][j-1]+dis[k][i],dp[i][j])
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <iostream>
#define go(a,b) for(int i=a;i<=b;++i)
#define INF 0x3f3f3f3f
#define mst(a, b) memset(a, (b), sizeof(a))
#define MOD 100000007
#define ll long long
#define lson node<<1, l, mid
#define rson node<<1|1, mid+1, r
const int maxn = 5005;
using namespace std;
int edgenum ;
struct Edge {
int to,cap,next;
}edge[maxn];
int n, m, t;
int fa[maxn][maxn];
int dp[maxn][maxn];
int head[maxn];
void init() {
edgenum = 0;
mst(head, -1);
}
void addEdge(int u,int v,int w) {
edge[edgenum].cap = w;
edge[edgenum].to = v;
edge[edgenum].next = head[u];
head[u] = edgenum;
edgenum++;
}
void dfs(int u,int step)
{
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
int dist = edge[i].cap;
if (dp[v][step + 1] > dp[u][step] + dist && dp[u][step] + dist <= t) {
dp[v][step + 1] = dp[u][step] + dist;
fa[v][step + 1] = u;
dfs(v, step + 1);
}
}
}
void print(int u,int i) {
if (u == 1) {
printf("1 ");
return;
}
else {
print(fa[u][i], i - 1);
}
printf("%d ", u);
if (u == n)
printf("\n");
}
int main() {
init();
scanf("%d%d%d", &n, &m, &t);
for (int i = 1; i <= m; ++i) {
int u, v, d;
scanf("%d%d%d", &u, &v, &d);
addEdge(u, v, d);
}
for (int i = 1; i <= n + 1; i++) {
for (int j = 1; j <= n + 1; j++) {
dp[i][j] = INF;
}
}
dp[1][1] = 0;
dfs(1, 1);
for (int i = n; i >= 1; i--) {
if (dp[n][i] <= t) {
cout << i << endl;
print(n, i);
return 0;
}
}
return 0;
}