P1144 最短路计数
BFS
- 由于是无向无权图,采用BFS
- 自环对于最短路无影响
- 重边和其它边对最短路径数的影响是一样的,不用做特别处理
- 采用dp思想即可统计出1号点到每个点的最短路径数
BFS 只入队一次,出队一次,可以抽象成拓扑图。
因为它可以保证被更新的点的父节点一定已经是最短距离了,并且这个点的路径数已经更新完成。
const int N=1e6+10;
vector<int> g[N];
int dist[N];
bool vis[N];
int cnt[N];
int n,m;
void bfs()
{
queue<int> q;
memset(dist,-1,sizeof dist);
q.push(1);
dist[1]=0;
cnt[1]=1;
while(q.size())
{
int t=q.front();
q.pop();
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i];
if(dist[j] == -1)
{
dist[j] = dist[t]+1;
cnt[j]=cnt[t];
q.push(j);
}
else if(dist[j] == dist[t]+1)
{
cnt[j]=(cnt[j]+cnt[t])%mod;
}
}
}
}
int main()
{
ios;
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
bfs();
for(int i=1;i<=n;i++)
if(dist[i] == -1) cout<<0<<endl;
else cout<<cnt[i]<<endl;
//system("pause");
}
\(dijkstra\)
\(dijkstra\)每个点只出队一次,也可以抽象成拓扑图。
由于每一个出队的点一定已经是最短距离,并且这个点的路径数已经更新完成。
const int N=1e6+10;
vector<PII> g[N];
int dist[N];
bool vis[N];
int f[N];
int n,m;
void dijkstra()
{
memset(dist,0x3f,sizeof dist);
priority_queue<PII,vector<PII>,greater<PII> > heap;
dist[1]=0;
heap.push({0,1});
f[1]=1;
while(heap.size())
{
int t=heap.top().se;
heap.pop();
if(vis[t]) continue;
vis[t]=true;
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i].fi,w=g[t][i].se;
if(dist[j] > dist[t]+w)
{
dist[j]=dist[t]+w;
f[j]=f[t];
heap.push({dist[j],j});
}
else if(dist[j] == dist[t]+w)
{
f[j]=(f[j]+f[t])%mod;
}
}
}
}
int main()
{
ios;
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
g[a].pb({b,1});
g[b].pb({a,1});
}
dijkstra();
for(int i=1;i<=n;i++)
if(dist[i] == INF) cout<<0<<endl;
else cout<<f[i]<<endl;
//system("pause");
}