ABC164_E 分层图
二维费用Dijkstra
在每个点要考虑点权\(c[i]\)影响当前可达的位置以及当前点的转换代价为\(d[i]\)
从上限看,如果超过了\(lim = 50 * (n - 1)\)最大银币需求那么就是简单跑一遍\(Dijkstra\)
所以要考虑的点就是当前节点携带的银币总量,记录一下这个状态作为\(dis[i][j]\)把问题化成我们常见的模型,用来跑朴素的\(Dijkstra\),不断"绕圈"并且把状态截止到\(dis[i][lim]\)停下.
边数\(E = n\cdot (lim + 1) + 2m\cdot (lim + 1),\)点数\(V = n\cdot (lim + 1)\)。
跑一遍\(Dijkstra\)的复杂度是\(O((V + E)logV)\),足够。
具体的代码细节会注释一下
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl '\n'
#define pii pair<int, int>
#define int long long
using namespace std;
using ll = long long;
using LD = long double;
int T;
const int mod = 998244353;
const ll inf = 3e18;
int n, m, s;
struct node {
int v, coin, w;
bool operator<(const node &u) const { return w > u.w; }
};
struct edge {
int v, cost, w;
};
const int N = 55, lim = 2450;
int dis[N][lim + 5], c[N], d[N];
bool vis[N][lim + 5];
vector<edge> g[N];
void solve() {
cin >> n >> m >> s;
for (int i = 1; i <= m; ++i) {
int u, v, coin, w;
cin >> u >> v >> coin >> w;
g[u].push_back({v, coin, w});
g[v].push_back({u, coin, w});
}
for (int i = 1; i <= n; ++i) {
cin >> c[i] >> d[i];
}
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= lim; ++j) {
dis[i][j] = inf;
}
}
//状态限定到lim内
if (s > lim)
s = lim;
priority_queue<node> hp;
hp.push({1, s, dis[1][s] = 0});
while (hp.size()) {
auto [u, coin, dist] = hp.top();
hp.pop();
if (dist < dis[u][coin])
continue;
if (vis[u][coin])
continue;
vis[u][coin] = 1;
//1.尝试进行金币转银币的操作
//对当前点进行绕圈
int ncoin = coin + c[u];
if (ncoin > lim) {
ncoin = lim;
}
if (dis[u][ncoin] > dist + d[u]) {
dis[u][ncoin] = dist + d[u];
hp.push({u, ncoin, dis[u][ncoin]});
}
//正常跑Dijkstra
for (auto [v, cost, w] : g[u]) {
if (cost > coin)
continue;
int ncoin = coin - cost;
if (dis[v][ncoin] > dist + w) {
dis[v][ncoin] = dist + w;
hp.push({v, ncoin, dis[v][ncoin]});
}
}
}
for (int i = 2; i <= n; ++i) {
int ans = inf;
for (int j = 0; j <= lim; ++j)
ans = min(ans, dis[i][j]);
cout << ans << "\n";
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(0);
T = 1;
// cin >> T;
while (T--)
solve();
return 0;
}

浙公网安备 33010602011771号