给出一个 N 个顶点 M 条边的无向无权图,顶点编号为 1~N。问从顶点 1 开始,到其他每个点的最短路有几条。
对于每个点,如果有另一个点能够转移过来,那就加上转移过来的点的值
如果要更新,那就等于转移过来的点的值
注意取模,并且开大数组
我写了两个版本
ans1:(Dijkstra+堆优化)
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } int n,m; int head[100006],nxt[400006],to[400006],v[400006]; int total=0; void add(int x,int y){ total++; to[total]=y; nxt[total]=head[x]; head[x]=total; v[total]=1; return ; } struct node{ int u,v; bool operator<(const node &x) const{return u>x.u;} }; int book[100006]; int dis[100006]; int cnt[100006]; priority_queue <node> Q; int mod=100003; void dij(int x){ memset(dis,127,sizeof(dis)); dis[x]=0; cnt[x]=1; node h; h.v=x,h.u=0; Q.push(h); while(!Q.empty()){ int x=Q.top().v; Q.pop(); if(book[x]) continue; book[x]=1; for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]==dis[x]+v[e]) cnt[to[e]]=(cnt[to[e]]+cnt[x])%mod; if(dis[to[e]]>dis[x]+v[e]){ dis[to[e]]=dis[x]+v[e]; cnt[to[e]]=cnt[x]; cnt[to[e]]%=mod; node k; k.v=to[e],k.u=dis[to[e]]; Q.push(k); continue; } } } return ; } int main(){ n=rd(),m=rd(); for(int i=1;i<=m;i++){ int x=rd(),y=rd(); add(x,y),add(y,x); } dij(1); for(int i=1;i<=n;i++){ write(cnt[i]),puts(""); } return 0; }
ans2:(SPFA)
#include<iostream> #include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline void write(int x){ if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); return ; } int n,m; int head[100006],nxt[400006],to[400006],v[400006]; int total=0; void add(int x,int y){ total++; to[total]=y; nxt[total]=head[x]; head[x]=total; return ; } queue <int> Q; int book[100006]; int dis[100006]; int cnt[100006]; int mod=100003; void spfa(int x){ memset(dis,127,sizeof(dis)); dis[x]=0; book[x]=1; cnt[x]=1; Q.push(x); while(!Q.empty()){ int x=Q.front(); Q.pop(); book[x]=0; for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]==dis[x]+1) cnt[to[e]]=(cnt[to[e]]+cnt[x])%mod; if(dis[to[e]]>dis[x]+1){ dis[to[e]]=dis[x]+1; cnt[to[e]]=cnt[x]; if(!book[to[e]]) book[to[e]]=1,Q.push(to[e]); } } } return ; } int main(){ n=rd(),m=rd(); for(int i=1;i<=m;i++){ int x=rd(),y=rd(); add(x,y),add(y,x); } spfa(1); for(int i=1;i<=n;i++){ write(cnt[i]),puts(""); } return 0; }