洛谷P2371 [国家集训队] 墨墨的等式 题解 同余最短路
题目链接:https://www.luogu.com.cn/problem/P2371
参考博客:
- oi wiki https://oi-wiki.org/graph/mod-shortest-path/
- xht大佬的博客 https://www.luogu.com.cn/article/tgfwb3v0
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
int n, a[15], x;
long long L, R, dis[maxn];
bool vis[maxn];
struct Edge { int v, w; };
vector<Edge> g[maxn];
struct Node {
int u;
long long dis;
bool operator < (const Node &b) const {
return dis > b.dis;
}
};
void dijkstra() {
priority_queue<Node> que;
fill(dis, dis+x, -1ll);
dis[0] = 0;
que.push({0, 0});
while (!que.empty()) {
Node nd = que.top();
que.pop();
int u = nd.u;
long long _dis = nd.dis;
if (vis[u]) continue;
vis[u] = true;
for (int i = 2; i <= n; i++) {
int v = (u + a[i]) % x;
if (dis[v] == -1 || dis[v] > dis[u] + a[i]) {
dis[v] = dis[u] + a[i];
que.push({ v, dis[v] });
}
}
}
}
int main() {
cin >> n >> L >> R;
for (int i = 1; i <= n; i++)
cin >> a[i];
x = a[1];
dijkstra();
long long ans = 0;
for (int i = 0; i < x; i++) {
if (dis[i] == -1)
continue;
if (dis[i] <= R)
ans += (R - dis[i]) / x + 1;
if (dis[i] <= L-1)
ans -= (L - 1 - dis[i]) / x + 1;
}
printf("%lld\n", ans);
return 0;
}
浙公网安备 33010602011771号