题意:
给 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 50∗N 的银币就可以到任意点。
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;
}