题解【洛谷P1144】最短路计数
我们考虑在每一次 Dijkstra 算法时,记录一下从 \(1 \sim i\) 最短路径的条数。
具体地说,我们在每一次遍历节点时:
- 如果 \(dist_v = dist_u + 1\),那么 \(cnt_v += cnt_u\);
- 如果 \(dist_v > dist_u + 1\),那么 \(cnt_v = cnt_u\)。
注意判等于要放在判大于之前。
#include <bits/stdc++.h>
using namespace std;
const int N = 1000003, M = 4000003, mod = 100003;
int n, m;
int tot, head[N], ver[M], nxt[M];
int dist[N], cnt[N];
bool vis[N];
inline void add(int u, int v)
{
    ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
inline void Dij()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    cnt[1] = 1;
    priority_queue <pair <int, int> > q;
    q.push(make_pair(0, 1));
    while (!q.empty())
    {
        int u = q.top().second; q.pop();
        if (vis[u]) continue;
        vis[u] = 1;
        for (int i = head[u]; i; i = nxt[i])
        {
            int v = ver[i], w = 1;
            if (dist[v] == dist[u] + w)
                (cnt[v] += cnt[u]) %= mod;
            if (dist[v] > dist[u] + w)
            {
                dist[v] = dist[u] + w;
                cnt[v] = cnt[u];
                q.push(make_pair(-dist[v], v));
            }
        }
    }
}
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i+=1)
    {
        int u, v;
        cin >> u >> v;
        add(u, v), add(v, u);
    }
    Dij();
    for (int i = 1; i <= n; i+=1)
    {
        cout << cnt[i] % mod << endl;
    }
    return 0;
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号