题目:https://www.luogu.org/problemnew/show/P1144
spfa跑最短路的同时记录cnt数组表示到达方案数。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,a,b,head[1000005],ct,dis[1000005],cnt[1000005],hp[10000005],h=1,t=1,p=100003; bool vis[1000005]; struct N{ int to,next; }edge[4000005]; void add(int x,int y) { ct++; edge[ct].to=y; edge[ct].next=head[x]; head[x]=ct; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } memset(dis,11,sizeof dis); dis[1]=0;cnt[1]=1; hp[h]=1;vis[1]=1; while(1) { bool fd=0,fj=0; if(h==t)fd=1; for(int i=head[hp[h]];i;i=edge[i].next) { int u=edge[i].to; if(dis[u]>dis[hp[h]]+1) { if(!vis[u]) { t++; if(t>10000005)t=1; hp[t]=u; fj=1; } vis[u]=1; dis[u]=dis[hp[h]]+1; cnt[u]=cnt[hp[h]]%p; } else if(dis[u]==dis[hp[h]]+1)//! { if(!vis[u]) { t++; if(t>10000005)t=1; hp[t]=u; fj=1; } vis[u]=1; cnt[u]+=cnt[hp[h]]; cnt[u]%=p; } } if(fd&&!fj)break; h++; if(h>10000005)h=1; } for(int i=1;i<=n;i++) printf("%d\n",cnt[i]%p); return 0; }