AcWing 1134. 最短路计数


题目传送门

一、BFS方法

#include 
using namespace std;
const int N = 4e5 + 10;
const int mod = 100003;
int h[N], ne[N], e[N], idx;
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int cnt[N];  //从顶点1开始,到其他每个点的最短路有几条
int dist[N]; //最短距离
int n, m;
void bfs() {
    memset(dist, 0x3f, sizeof dist);
    queue q;
    q.push(1);
    cnt[1] = 1;  //从顶点1开始,向顶点1的最短路有1条
    dist[1] = 0; //距离为0
    while (q.size()) {
        int t = q.front();
        q.pop();
        for (int i = h[t]; ~i; i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[t] + 1) {
                dist[j] = dist[t] + 1;
                q.push(j);
                cnt[j] = cnt[t];
            } else if (dist[j] == dist[t] + 1)
                cnt[j] = (cnt[j] + cnt[t]) % mod;
        }
    }
}
int main() {
    memset(h, -1, sizeof h);
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int a, b, c;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    bfs();
    for (int i = 1; i <= n; i++)
        printf("%d\n", cnt[i]);
}

二、Dijkstra方法

#include 
using namespace std;
typedef pair PII;
const int N = 100010, M = 400010;
const int MOD = 100003;

int n, m;
int cnt[N];
int d[N];
bool st[N];
int h[N], e[M], ne[M], idx;
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dijkstra(int start) {
    memset(d, 0x3f, sizeof d);
    d[start] = 0;
    //出发点到自己的最短路径只能有1条
    cnt[start] = 1;
    //小顶堆q
    priority_queue, greater> q;
    q.push({0, start});

    while (q.size()) {
        auto t = q.top();
        q.pop();

        int u = t.second, dist = t.first;
        if (st[u]) continue;
        st[u] = true;

        for (int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if (d[j] > dist + 1) {
                d[j] = dist + 1;
                cnt[j] = cnt[u];
                q.push({d[j], j});
            }
            //只有当当前值可以被更新时才加入到队列当中,(bfs同理)
            else if (d[j] == dist + 1)
                cnt[j] = (cnt[j] + cnt[u]) % MOD;
        }
    }
}

int main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    while (m--) {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    dijkstra(1);
    for (int i = 1; i <= n; i++) cout << cnt[i] << endl;
    return 0;
}

相关