持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情
最短路计数
题目描述
给出一个 个顶点 条边的无向无权图,顶点编号为 。问从顶点 开始,到其他每个点的最短路有几条。
输入格式
第一行包含 个正整数 ,为图的顶点数与边数。
接下来 行,每行 个正整数 ,表示有一条由顶点 连向顶点 的边,请注意可能有自环与重边。
输出格式
共 行,每行一个非负整数,第 行输出从顶点 到顶点 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 后的结果即可。如果无法到达顶点 则输出 。
样例 #1
样例输入 #1
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
样例输出 #1
1
1
1
2
4
提示
到 的最短路有 条,分别为 条 和 条 (由于 的边有 条)。
对于 的数据,;
对于 的数据,;
对于 的数据,,。
思路
这是一道最短路问题用做,思路就是在原来的板子的基础上用一个 数组来记录最短路的距离,每次吧队头的路径条数赋值给扩充到的ans就结束了。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#define ll long long
#define AC return
#define Please 0
using namespace std;
const int N=1000100;
const int mod=100003;
typedef pair<int,int>PII;
int e[N],dist[N],idx=0,ne[N],h[N],n,m,ans[N];
bool st[N];
inline void add(int a,int b,int c){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
inline int read(){//快读
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
AC x*f;
}
inline void dijkstra(){
memset(dist,0x3f,sizeof dist);
memset(ans,0,sizeof ans);
dist[1]=0;
ans[1]=1;
priority_queue<PII,vector<PII>,greater<PII>>heap;
heap.push({0,1});
while(heap.size()){
auto t=heap.top();
int y=t.second;
heap.pop();
if(st[y]) continue;
st[y]=1;
for(int i=h[y];i!=-1;i=ne[i]){
int x=e[i];
if(dist[x]>dist[y]+1){
dist[x]=dist[y]+1;
ans[x]=ans[y];
heap.push({dist[x],x});
}
else if(dist[x]==dist[y]+1){
ans[x]+=ans[y];
ans[x]%=mod;
}
}
}
}
int main(){
n=read(),m=read();
memset(h,-1,sizeof h);
while(m--){
int a,b;
a=read(),b=read();
add(a,b,1);
add(b,a,1);
}
dijkstra();
for(int i=1;i<=n;i++){
cout<<ans[i]<<endl;
}
AC Please;
}
希望能帮助到大家()!