代码源 #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

数据范围

1N10^61M2×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 }

 

posted @ 2022-05-20 16:49  aa小怪兽  阅读(30)  评论(0)    收藏  举报