C. Journey(拓扑dp)

这是真没想到,其实也不难的

d p . , 1 e 9 考虑dp.但是状态有点存不下,毕竟每条路的花费到了1e9级别

d p [ i ] [ j ] 1 i j 那不如令dp[i][j]表示从1到i走了j个节点的最小花费

, 1 0 那么拓扑排序,1是入度为0的点

一层一层维护下来

#include <bits/stdc++.h>
using namespace std;
const int maxn=5009;
typedef long long ll;
#define f first
#define s second
#define GO std::ios::sync_with_stdio(false)
int n,m,in[maxn],path[maxn][maxn];
typedef pair<int,int>p;
vector<p>vec[maxn];
queue<int>q;
int dp[maxn][maxn],t;
void TuoPuSort()
{
	//dp[i][j]?????i??????j???????С??? 
	for(int i=0;i<=5000;i++)
	for(int j=0;j<=5000;j++)
		dp[i][j]=1e9+10;
	dp[1][1]=0;//???1?????0,???????1???? 
	for(int i=1;i<=n;i++)	if(in[i]==0)	q.push(i);
	while( !q.empty() )
	{
		int u=q.front(); q.pop();
		for(int i=0;i<vec[u].size();i++)
		{
			p v=vec[u][i];
			if( --in[v.f]==0 )	q.push(v.f);
			for(int j=2;j<=n;j++)
			{
				if( dp[v.f][j]>dp[u][j-1]+v.s)
				{
					dp[v.f][j]=dp[u][j-1]+v.s;
					path[v.f][j]=u;
				}
			}
		}
	} 
}
void dfs(int now,int num)
{
	if(num==1)	{ cout<<1<<" "; return;}
	dfs(path[now][num],num-1);
	cout << now << " ";
}
int main()
{
	GO;
	cin >> n >> m >> t;
	for(int i=1,l,r,w;i<=m;i++)
	{
		cin >> l >> r >> w;
		vec[l].push_back( p(r,w) ); 
		in[r]++;
	}
	TuoPuSort();
	int res=0;
	for(int i=n;i>=1;i--)
		if(dp[n][i]<=t)	{ res=i; break; }
	cout<<res<<endl;
	dfs(n,res);
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107285788