C. Journey(拓扑排序+DP)
一点不相关的话:好久没有更新博客了,当我再次看到这些,甚至都想象不到这些都是我写的。嗳,可能这就是命运多舛吧。去年打完最后一场ICPC后,就开始抉择是考研还是继续打下去,但是好像没有人陪我打下去了,ACM一个人真的很难坚持(其实有很多话想说,但是,我现在不想再回忆,这样只会消沉自己的情绪。)。最终,在询问过已经毕业的学长之后,我选择了去考研。今天考研视频网课没有更新,一下午在捣鼓clash(被墙阻隔的网速属实不好受)。然后想着来做两道题吧,因此才有了这篇题解博客。
接下来是正文23333333…
题意:给一张
个点
条边的
(有向无环图),询问从
在距离不超过
的条件下,最多经过几个点,并且输出路径。
题解:因为是
,因此我们可以直接拓扑排序,然后在排序过程中处理一个
,
代表到达
经过了
个点的最少花费。
并且顺便记录路径。
代码
#include<bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
#define dbg(args...) \
do{ \
cout << "\033[32;1m" << #args << " -> "; \
err(args); \
} while(0)
#else
#define dbg(...)
#endif
void err()
{
cout << "\033[39;0m" << endl;
}
template <template <typename...> class T, typename t, typename... Args>
void err(T<t> a, Args... args)
{
for (auto x : a) cout << x << ' ';
err(args...);
}
template <typename T, typename... Args>
void err(T a, Args... args)
{
cout << a << ' ';
err(args...);
}
/****************************************************************************************************/
const int N = 5024;
int n,m,T,deg[N];
#define P pair<int,int>
#define LL long long
vector<P> E[N];
vector<int> ret;
bool vis[N];
LL dp[N][N];
short int pre[N][N];
void top_sort()
{
queue<int> q;
for(int i = 1; i <= n; ++i) {
if(deg[i] == 0) {
q.push(i);
}
}
while(!q.empty()) {
int u = q.front();
q.pop();
// dbg(u);
ret.emplace_back(u);
for(const auto &i : E[u]) {
int v = i.first, w = i.second;
for(int j = 2; j <= n; ++j) {
if(dp[u][j - 1] + w < dp[v][j]) {
dp[v][j] = dp[u][j - 1] + w;
pre[v][j] = u;
}
}
if(--deg[v] == 0) {
q.push(v);
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in","r",stdin);
#endif
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> m >> T;
for(int i = 0,u, v, w; i < m; ++i) {
cin >> u >> v >> w;
E[u].push_back(P(v,w));
deg[v]++;
}
memset(dp, 0x3f, sizeof dp);
dp[1][1] = 0;
top_sort();
for(int i = n; i >= 2; --i) {
if(dp[n][i] <= T) {
cout << i << '\n';
vector<int> ans;
for(int j = i, t = n; j >= 1; --j) {
ans.emplace_back(t);
t = pre[t][j];
}
for(int j = ans.size() - 1; j >= 0; --j) {
cout << ans[j] << " \n"[j == 0];
}
break;
}
}
return 0;
}