https://www.luogu.org/problem/show?pid=1144#sub
题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1~N。问从顶点1开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
输入第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可。如果无法到达顶点i则输出0。
输入输出样例
输入样例#1:
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出样例#1:
1 1 1 2 4
说明
1到5的最短路有4条,分别为2条1-2-4-5和2条1-3-4-5(由于4-5的边有2条)。
对于20%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N<=1000000,M<=2000000。
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 6 using namespace std; 7 8 const int mod(100003); 9 const int N(1000000+15); 10 const int M(2000000+15); 11 int n,m,u,v,w; 12 13 int head[N],sumedge; 14 struct Edge 15 { 16 int u,v,next; 17 Edge(int u=0,int v=0,int next=0): 18 u(u),v(v),next(next){} 19 }edge[M<<1]; 20 void ins(int u,int v) 21 { 22 edge[++sumedge]=Edge(u,v,head[u]); 23 head[u]=sumedge; 24 } 25 26 queue<int>que; 27 int dis[N],cnt[N],inq[N]; 28 void SPFA() 29 { 30 for(int i=1;i<=n;i++) dis[i]=N*10; 31 que.push(1); inq[1]=1; dis[1]=0; cnt[1]=1; 32 for(int fro;!que.empty();) 33 { 34 fro=que.front();que.pop();inq[fro]=0; 35 if(fro==n) continue; 36 for(int i=head[fro];i;i=edge[i].next) 37 { 38 int v=edge[i].v; 39 if(dis[v]==dis[fro]+1) 40 cnt[v]=(cnt[v]%mod+cnt[fro]%mod)%mod; 41 else if(dis[v]>dis[fro]+1) 42 { 43 dis[v]=dis[fro]+1; 44 cnt[v]=cnt[fro]%mod; 45 if(!inq[v]) que.push(v),inq[v]=1; 46 } 47 } 48 } 49 } 50 51 int main() 52 { 53 scanf("%d%d",&n,&m); 54 for(int i=1;i<=m;i++) 55 { 56 scanf("%d%d",&u,&v); 57 ins(u,v);ins(v,u); 58 } 59 SPFA(); 60 for(int i=1;i<=n;i++) printf("%d ",cnt[i]); 61 return 0; 62 }