代码源 #810.最短路计数
题目描述
给出一个 N 个顶点 M 条边的无向无权图。
问从顶点 1 开始,到其他每个点的最短路有几条。
输入格式
第 1 行包含两个正整数 N,M。
接下来 M 行,每行两个正整数 x,y 表示存在一条由顶点 x 到顶点 y 的边。(可能存在重边和自环)
输出格式
输出 N 行,每行一个非负整数。
第 i 行输出从顶点 1 到顶点 i 的不同最短路个数。
由于数据可能很大,你只需要输出 ansmod100003 的结果。
若顶点 1 不能到达顶点 i,请输出 0。
样例输入
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
样例输出
1
1
1
2
4
数据范围
1≤N≤10^6,1≤M≤2×10^6。
提示
由于数据量较大,请使用较为快速的输入/输出方式。
题目大意:
大意就是,给出一个无边权的无向图,求从顶点1开始到所有点的最短路的个数有多少个。
思路:
我们可以从1号点开始走一遍bfs,不断拓展出新的点出来,可以保证的是,如果这个点是第一次入队,那么这个点的最短路的距离就等于父节点的距离+1。然后判断一下,对于一个点a,如果a的最短路距离等于b的最短路距离+1,那么从b到a这条路也是最短路,所以更新a点的最短路距离的个数。
AC代码(带注释):
1 #include<algorithm> 2 #include<iomanip> 3 #include<stdio.h> 4 #include<cstdio> 5 #include<math.h> 6 #include<iostream> 7 #include<cstring> 8 #include<stack> 9 #include<queue> 10 #include<string.h> 11 #include<set> 12 #include<map> 13 14 using namespace std; 15 #define endl '\n' 16 #define ull unsigned long long 17 #define ll long long 18 #define ld long double 19 #define PII pair<int,int> 20 const int N = 1e6 + 7; 21 const int mod = 100003; 22 23 std::queue<int>q; 24 std::vector<int>to[N]; 25 int dp[N], vis[N], cnt[N]; 26 int n, m, a, b; 27 28 int main() 29 { 30 //要是超时可能就是没加上这句话 31 ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); 32 cin >> n >> m; 33 while (m--)//读入数据 34 { 35 cin >> a >> b; 36 //无向图连通 37 to[a].push_back(b); 38 to[b].push_back(a); 39 } 40 41 q.push(1);vis[1] = 1;//1号点入队 42 dp[1] = 0; cnt[1] = 1;//初始化1号点距离为1 43 while (!q.empty())//bfs 44 { 45 b = q.front(); q.pop(); 46 for (auto a : to[b])//遍历和b号点相连接的点 47 { 48 if (!vis[a])//如果没有入队 49 { 50 dp[a] = dp[b] + 1;//最短路距离 51 q.push(a);vis[a] = 1;//入队 52 } 53 //如果1到a的最短路距离等于1到b的最短路距离+1 54 if (dp[a] == dp[b] + 1) 55 { 56 cnt[a] = (cnt[a] + cnt[b]) % mod; 57 } 58 } 59 } 60 for (int i = 1; i <= n; i++) 61 { 62 cout << cnt[i] << endl; 63 } 64 return 0; 65 }

浙公网安备 33010602011771号