【算法】最短路计数(计算最短路的数量)

编程入门 行业动态 更新时间:2024-10-26 09:26:48

【<a href=https://www.elefans.com/category/jswz/34/1770096.html style=算法】最短路计数(计算最短路的数量)"/>

【算法】最短路计数(计算最短路的数量)

题目 

        给出一个 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;
}

更多推荐

【算法】最短路计数(计算最短路的数量)

本文发布于:2023-11-15 10:30:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1598212.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:算法   数量

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!