洛谷P1144 最短路计数 BFS
网址:https://www.luogu.org/problem/P1144
题意:
给出一个$N$个顶点$M$条边的无向无权图,顶点编号为$1$~$N$。问从顶点$1$开始,到其他每个点的最短路有几条,可能有自环与重边。输出$ans$ $mod100003$后的结果即可。如果无法到达顶点$i$则输出$0$。
题解:
用一个$cnt$数组记录$1$点到达某个点的最短路径的条数,如果在某个时候已经求出$u$的深度,如果访问的点是$v$且$v$的深度等于$u$的深度$+1$,则可知这条$u$至$v$的边在$1$到$v$的最短路径上,所以$cnt[v]=cnt[v]+cnt[u]$; 由加法原理可知,如果有重边,累加$cnt[u]$即可。求解使用$bfs$即可。(如果是带权图,则在松弛的时候进行更新即可)。
AC代码:
#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; int dep[1000005], vis[1000005], cnt[1000005]; vector<int>Edge[1000005]; void bfs(int n) { queue<int>que; que.push(1); dep[1] = 1, cnt[1] = 1, vis[1] = 1; while (!que.empty()) { int u = que.front(); que.pop(); for (auto v : Edge[u]) { if (!vis[v]) { dep[v] = dep[u] + 1; vis[v] = 1; que.push(v); } if (dep[v] == dep[u] + 1) cnt[v] = (cnt[v] + cnt[u]) % 100003; } } for (int i = 1; i <= n; ++i) cout << cnt[i] << endl; } int main() { int n, m, a, b; cin >> n >> m; for (int i = 0; i < m; ++i) { cin >> a >> b; if (a != b) { Edge[a].push_back(b); Edge[b].push_back(a); } } bfs(n); return 0; }