AtCoder Beginner Contest 164 E - Two Currencies

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:

n n n 个城市, n n n 条路, s s s 个银币,每条路需要花费 a I a_I aI 个银币和 b i b_i bi 分钟,可以在第 i i i个城市花费 d i d_i di 分钟获得 c i c_i ci 银币(无限次),求从 1 1 1 2... n 2...n 2...n 最少花费的时间。

最短路, f [ i ] [ j ] f[i][j] f[i][j] 代表到第i个城市身上有 j j j 个银币的最少花费时间,由于 a a a最大为 50 50 50,那么身上只要有 50 ∗ N 50*N 50N 的银币就可以到任意点。

AC代码:

const int N = 55;
struct P
{
	int v, a, b;
};
int n, m, s;
vector<P> G[N];
int c[N], d[N];
ll f[N][N * N];
int main()
{
	sddd(n, m, s);
	s = min(s, 2500);
	rep(i, 1, m)
	{
		int u, v, a, b;
		sdd(u, v);
		sdd(a, b);
		G[u].pb({v, a, b});
		G[v].pb({u, a, b});
	}
	rep(i, 1, n)
		sdd(c[i], d[i]);
	rep(i, 0, N - 1)
	{
		rep(j, 0, N * N - 1)
			f[i][j] = INF;
	}
	f[1][s] = 0;
	typedef tuple<ll, int, int> T;
	priority_queue<T, vector<T>, greater<T>> qu;
	qu.push(T(0, 1, s));
	while (!qu.empty())
	{
		ll t = get<0>(qu.top());
		int u = get<1>(qu.top()), w = get<2>(qu.top());
		qu.pop();
		if (f[u][w] > t)
			continue;
		rep(i, 0, G[u].size())
		{
			int v = G[u][i].v, a = G[u][i].a, b = G[u][i].b;
			if (w >= a && f[v][w - a] > t + b)
			{
				f[v][w - a] = t + b;
				qu.push(T(t + b, v, w - a));
			}
		}
		if (f[u][min(w + c[u], 2500)] > t + d[u])
		{
			f[u][min(w + c[u], 2500)] = t + d[u];
			qu.push(T(t + d[u], u, min(w + c[u], 2500)));
		}
	}
	rep(i, 2, n)
	{
		ll ans = INF;
		rep(j, 0, 2500)
			ans = min(ans, f[i][j]);
		pld(ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值