题目描述
给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N。问从顶点11开始,到其他每个点的最短路有几条。
输入格式
第一行包含22个正整数N,MN,M,为图的顶点数与边数。
接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边。
输出格式
共NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003ansmod100003后的结果即可。如果无法到达顶点ii则输出00。
输入输出样例
输入 #1
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出 #1
1 1 1 2 4
说明/提示
11到55的最短路有44条,分别为22条1-2-4-51−2−4−5和22条1-3-4-51−3−4−5(由于4-54−5的边有22条)。
对于20\%20%的数据,N ≤ 100N≤100;
对于60\%60%的数据,N ≤ 1000N≤1000;
对于100\%100%的数据,N<=1000000,M<=2000000N<=1000000,M<=2000000。
题解:又是一道最短路计数恩 ,好像比上一个版本要更好哦
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; const int N=1000001; const int mod=100003; const int oo=0x3f3f3f3f; int cnt,head[N],yxr=oo,B,E,P; struct node{ int to,next; }e[N*2]; void add(int u,int v){ e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } int vis[N],dis[N],ans[N],n,m,u,v; queue<int>q; void SPFA(int s){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); vis[s]=1; dis[s]=0; q.push(s); int x,v; ans[1]=1; while(!q.empty()){ x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i;i=e[i].next){ v=e[i].to; if(dis[v]>dis[x]+1){ dis[v]=dis[x]+1; ans[v]=ans[x]; if(!vis[v]) { q.push(v); vis[v]=1; } } else if(dis[v]==dis[x]+1) { ans[v]+=ans[x]; ans[v]%=mod; } //if(dis[v]>dis[x]+1){ // dis[v]=dis[x]+1; // if(!vis[v]) { vis[v]=1; q.push(v); } //} } } } int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d",&u,&v); add(u,v); add(v,u); } SPFA(1); for(int i=1;i<=n;i++) printf("%d ",ans[i]); return 0; }