洛谷P2371 [国家集训队] 墨墨的等式 题解 同余最短路

题目链接:https://www.luogu.com.cn/problem/P2371

参考博客:

  1. oi wiki https://oi-wiki.org/graph/mod-shortest-path/
  2. 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;
}
posted @ 2025-04-04 02:55  quanjun  阅读(43)  评论(0)    收藏  举报