最短路计数

116 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

最短路计数

题目描述

给出一个 NN 个顶点 MM 条边的无向无权图,顶点编号为 1N1\sim N。问从顶点 11 开始,到其他每个点的最短路有几条。

输入格式

第一行包含 22 个正整数 N,MN,M,为图的顶点数与边数。

接下来 MM 行,每行 22 个正整数 x,yx,y,表示有一条由顶点 xx 连向顶点 yy 的边,请注意可能有自环与重边。

输出格式

NN 行,每行一个非负整数,第 ii 行输出从顶点 11 到顶点 ii 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 ansmod100003 ans \bmod 100003 后的结果即可。如果无法到达顶点 ii 则输出 00

样例 #1

样例输入 #1

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5

样例输出 #1

1
1
1
2
4

提示

1155 的最短路有 44 条,分别为 2212451\to 2\to 4\to 52213451\to 3\to 4\to 5(由于 454\to 5 的边有 22 条)。

对于 20%20\% 的数据,1N1001\le N \le 100
对于 60%60\% 的数据,1N1031\le N \le 10^3
对于 100%100\% 的数据,1N1061\le N\le10^61M2×1061\le M\le 2\times 10^6

思路

这是一道最短路问题用dijkstradijkstra做,思路就是在原来的板子的基础上用一个ansans 数组来记录最短路的距离,每次吧队头的路径条数赋值给扩充到的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;
}

希望能帮助到大家(QAQQAQ)!