算法】最短路计数(计算最短路的数量)"/>
【算法】最短路计数(计算最短路的数量)
题目
给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1 到 N。
问从顶点 1 开始,到其他每个点的最短路有几条。
输入格式
第一行包含 2 个正整数 N,M,为图的顶点数与边数。
接下来 M 行,每行两个正整数 x,y,表示有一条顶点 x 连向顶点 y 的边,请注意可能有自环与重边。
输出格式
输出 N 行,每行一个非负整数,第 i 行输出从顶点 1 到顶点 i 有多少条不同的最短路,由于答案有可能会很大,你只需要输出对 100003 取模后的结果即可。
如果无法到达顶点 i 则输出 0。
数据范围
1≤ N ≤ 10^5
1 ≤ M ≤ 2×105
思路
由于该图为无向无权图,因此最短路为经过点最少的路径。
样例:
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
根据样例,我们得到下面这张图。
dist[]数组储存走到当前点,最少经过的点数。
1、如果在bfs过程中,后面的点 i 比他的前驱 j 的点数+1还要大,则说明当前dist[i]中储存的不是当前点 i 所经过的最小点数。更新点 i ,dist[ i ] = dist[ j ] + 1; cnt[ i ] = cnt[ j ]。
2、如果在bfs过程中,后面的点 i 与他的前驱 j 的点数+1相等,则说明从点 j 到达点 i 也是最短路。更新点 i , cnt[ i ] = cnt[ j ] + cnt[ i ]。(注意取模)
3、如果在bfs过程中,后面的点 i 比他的前驱 j 的点数+1要小,则不进行任何操作。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10,M = 4e5 + 10,MOD = 100003;
int n,m;
int h[N],e[M],ne[M],idx;
int dist[N],cnt[N];// cnt中储存最短路的个数
queue<int> q;void add(int a,int b)
{e[idx] = b,ne[idx] = h[a],h[a] = idx ++;
}void bfs()
{memset(dist,0x3f,sizeof(dist));dist[1] = 0;cnt[1] = 1;q.push(1);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;cnt[j] = cnt[t];q.push(j);}else if(dist[j] == dist[t] + 1){cnt[j] = (cnt[j] + cnt[t]) % MOD;}}}
}int main()
{memset(h,-1,sizeof(h));cin >> n >> m;int a,b;while(m --){scanf("%d%d",&a,&b);add(a,b);add(b,a);}bfs();for(int i = 1; i <= n; i ++){cout << cnt[i] << endl;}return 0;
}
更多推荐
【算法】最短路计数(计算最短路的数量)
发布评论