题目链接:D - Number of Shortest paths
题意:n座城m条路,走每一条路的时间为1,问从City 1 到City n 的最短路有几条
分析:定义w[i]表示到i城的最短路径数目,先令w[1]=1,表示从原点开始的最短路径数目有1条。
每次从now城又找到了到y城的最短路径,w[y]=w[y]+w[now];否则更新最短路,w[y]=w[now];
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int mod=1e9+7;
const int maxn=2e5+5;
int head[maxn],cnt;
int vis[maxn],dis[maxn];
int n,m,s=1;
int ans[maxn];
struct edge{
int to,next,w;
}e[maxn<<1];
void add(int from,int to,int w)
{
e[++cnt]={to,head[from],w};
head[from]=cnt;
}
struct node
{
int id,dis;
bool operator<(const node &a)const//重载小于运算符(大顶堆变小顶堆)
{
return a.dis<dis;
}
};
void dijkstra()
{
priority_queue<node>q;
q.push((node){s,0});
for(int i=1;i<=n;i++) dis[i]=inf;
dis[s]=0;
ans[1]=1;
while(q.size())
{
node now=q.top();
q.pop();
int u=now.id;
if(vis[u]) continue;//这个点出过了就找堆顶下一个
vis[u]=1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to,w=e[i].w;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
ans[v]=ans[u];
q.push((node){v,dis[v]});//队列只加不删(不好删) 松弛操作会更新最短路放入pq
}
else if(dis[u]+w==dis[v])
{
ans[v]=(ans[v]+ans[u])%mod;
}
}
}
}
int main()
{
cin>>n>>m;
while(m--)
{
int u,v;
cin>>u>>v;
add(u,v,1);
add(v,u,1);
}
dijkstra();
cout<<ans[n]<<endl;
}