同余最短路的转圈技巧
众所周知,在同余最短路算法中,我们选取基准物品的体积作为模数
算法介绍
不要从图论的角度考虑问题,而是回归本源:体积模
因此,往背包加入体积为
对于普通的完全背包,即边权等于
例题
P2371 墨墨的等式
以下是经典同余最短路问题「墨墨的等式」的转圈代码。它是普通的完全背包。
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 5e5 + 5;
int n, m, a[N], _a[N];
long long f[N], l, r, ans;
int main() {
cin >> n >> l >> r;
for(int i = 1; i <= n; i++) {
cin >> a[i];
if(!a[i]) n--, i--;
}
if(!n) cout << "0\n", exit(0);
memset(f, 0x3f, sizeof(f)), f[0] = 0;
sort(a + 1, a + n + 1), m = a[1];
for(int i = 1; i <= n; i++) _a[i] = a[i] % m; // 避免多次取模常数太大
for(int i = 2; i <= n; i++) {
for(int j = 0, lim = __gcd(a[i], m); j < lim; j++) {
for(int t = j, c = 0; c < 2; c += t == j) {
int p = t + _a[i];
if(p >= m) p -= m;
f[p] = min(f[p], f[t] + a[i]), t = p;
}
}
}
for(int i = 0; i < a[1]; i++) {
if(r >= f[i]) ans += max(0ll, (r - f[i]) / a[1] + 1);
if(l > f[i]) ans -= max(0ll, (l - 1 - f[i]) / a[1] + 1);
}
cout << ans << endl;
return 0;
}
P9140 背包
本题在完全背包的可行性基础上加入了权值这一维度。
如果我们将
对于两组背包方案
对于一组背包方案
根据
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int N = 1e5 + 5;
ll n, q, m = 1, w, V, f[N], c[55], v[55], _v[55], _d[55];
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> q;
for(int i = 1; i <= n; i++) {
cin >> v[i] >> c[i];
if(w * v[i] < m * c[i]) w = c[i], m = v[i];
}
for(int i = 1; i <= n; i++) _v[i] = v[i] % m, _d[i] = v[i] / m; // 避免多次取模和除法常数太大
for(int i = 1; i < m; i++) f[i] = -1e18;
for(int i = 1; i <= n; i++) {
for(int j = 0, lim = __gcd(v[i], m); j < lim; j++) {
for(int t = j, _ = 0; _ < 2; _ += t == j) {
int q = t + _v[i], d = _d[i];
if(q >= m) q -= m, d++;
f[q] = max(f[q], f[t] + c[i] - d * w), t = q;
}
}
}
for(int i = 1; i <= q; i++) {
cin >> V;
int p = V % m;
if(f[p] < -1e17) cout << "-1\n";
else cout << f[p] + V / m * w << "\n";
}
return 0;
}
和其它算法的对比
SPFA 跑同余最短路的复杂度依然是个谜。它的理论上界是
此外,在可以使用最大体积作为基准元素时,令
显然,转圈技巧比最短路好写,且适用范围没有任何限制,如 01-BFS 就无法解决第二道例题。
总结
同余最短路的本质是根据单调性值域定义域互换后将完全背包转化为体积模
笔者在研究「背包」一题的官方解法时,惊讶于其 “转两圈” 思想的巧妙。翻了一遍经典同余最短路题目,也没找到几篇除了 SPFA 和 Dijkstra 以外的题解,故分享给各位读者。
同余最短路还在写最短路?时代的眼泪!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效