P1608 路径统计&&P1144 最短路计数
相似的两道题
区别在于边权
ans数组记录方案数
如果是第一次更新那么方案数就等于更新他的节点的方案数
因为他们在一条路径上
如果此时节点的最短路等于上一个节点的最短路加上他们之间的距离
那么此时节点的方案数就加上上一个节点的方案数
P1144 最短路计数
spfa
//P1144 最短路计数 #include<bits/stdc++.h> using namespace std; const int mod=100003; const int inf=987654321; int n,m; vector<int> g[4000005]; int d[1000005],ans[1000005]; bool v[1000005]; inline void spfa(){ for(int i=1;i<=n;i++){ d[i]=inf; } queue<int> q; q.push(1); v[1]=1; d[1]=0; ans[1]=1; while(q.size()){ int x=q.front(); q.pop(); v[x]=0; int sz=g[x].size(); for(int i=0;i<sz;i++){ int y=g[x][i]; if(d[y]>d[x]+1){ d[y]=d[x]+1; ans[y]=ans[x]; if(!v[y]){ v[y]=1; q.push(y); } }else if(d[y]==d[x]+1){ ans[y]+=ans[x]; ans[y]%=mod; } } } } int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } spfa(); for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); } return 0; }
dij
//P1144 最短路计数 #include<bits/stdc++.h> using namespace std; const int mod=100003; const int inf=987654321; int n,m; vector<int> g[4000005]; int d[1000005],ans[1000005]; bool v[1000005]; inline void dij(){ for(int i=1;i<=n;i++){ d[i]=inf; } priority_queue<pair<int,int> >q; q.push(make_pair(0,1)); d[1]=0; while(q.size()){ int x=q.top().second; q.pop(); if(v[x]) continue; v[x]=1; ans[1]=1; int sz=g[x].size(); for(int i=0;i<sz;i++){ int y=g[x][i]; if(d[y]>d[x]+1){ d[y]=d[x]+1; ans[y]=ans[x]; q.push(make_pair(-d[y],y)); }else if(d[y]==d[x]+1){ ans[y]+=ans[x]; ans[y]%=mod; } } } } int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); g[x].push_back(y); g[y].push_back(x); } dij(); for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); } return 0; }
P1608 路径统计
dij
//P1608 路径统计 #include<bits/stdc++.h> using namespace std; const int mxm=8000005; const int mxn=2005; const int inf=987654321; int n,m; struct sc{ int nxt,to,w; }g[mxm]; int head[mxm],len; int d[mxn],ans[mxn]; bool v[mxn]; int mp[mxn][mxn]; inline void add(int u,int v,int w){ g[++len].to=v; g[len].w=w; g[len].nxt=head[u]; head[u]=len; } inline void dij(){ for(int i=1;i<=n;i++){ d[i]=inf; } priority_queue<pair<int,int> >q; q.push(make_pair(0,1)); d[1]=0; ans[1]=1; while(q.size()){ int x=q.top().second; q.pop(); if(v[x]) continue; v[x]=1; for(int i=head[x];i;i=g[i].nxt){ int y=g[i].to,w=g[i].w; if(d[y]>d[x]+w){ d[y]=d[x]+w; ans[y]=ans[x]; q.push(make_pair(-d[y],y)); }else if(d[y]==d[x]+w){ ans[y]+=ans[x]; } } } } int main(){ cin>>n>>m; for(int i=1;i<=m;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); if(!mp[x][y]){ mp[x][y]=z; add(x,y,z); }else if(mp[x][y]>z){ add(x,y,z); mp[x][y]=z; } } dij(); if(d[n]==inf) puts("No answer"); else cout<<d[n]<<" "<<ans[n]; return 0; }