CF 721C - C. Journey(拓扑排序+DP)

C. Journey(拓扑排序+DP)

一点不相关的话:好久没有更新博客了,当我再次看到这些,甚至都想象不到这些都是我写的。嗳,可能这就是命运多舛吧。去年打完最后一场ICPC后,就开始抉择是考研还是继续打下去,但是好像没有人陪我打下去了,ACM一个人真的很难坚持(其实有很多话想说,但是,我现在不想再回忆,这样只会消沉自己的情绪。)。最终,在询问过已经毕业的学长之后,我选择了去考研。今天考研视频网课没有更新,一下午在捣鼓clash(被墙阻隔的网速属实不好受)。然后想着来做两道题吧,因此才有了这篇题解博客。

接下来是正文23333333…

题意:给一张 n n n个点 m m m条边的 D A G DAG DAG(有向无环图),询问从 1 → n 1\rightarrow n 1n在距离不超过 T T T的条件下,最多经过几个点,并且输出路径。
题解:因为是 D A G DAG DAG,因此我们可以直接拓扑排序,然后在排序过程中处理一个 d p dp dp d p [ v ] [ j ] dp[v][j] dp[v][j]代表到达 v v v经过了 j j j个点的最少花费。
d p [ v ] [ j ] = m i n ( d p [ v ] [ j ] , d p [ u ] [ j − 1 ] + w ) dp[v][j] = min(dp[v][j], dp[u][j - 1] + w) dp[v][j]=min(dp[v][j],dp[u][j1]+w)
并且顺便记录路径。

代码

#include
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
#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;
}

你可能感兴趣的:(算法,CodeForces,动态规划)