P1144 最短路计数
这是一道记录起点到各点的最短路的数量的题目,实现的操作就是堆优化的Dijkstra+计数操作,这里主要讲解一下计数操作。
我们可以开一个数组ans[i],这个数组记录的是起点到i点的最短路径的个数,接下来在实行Dijkstra的时候每次判断是否需要更新最短路的时候无非3种情况。
1.dist[j] > w[i] + dsitance
这种情况说明发现到达j点的新的最短路,这时的处理是
ans[j] = ans[v];
直接用去往ans[ver]的方法数覆盖ans[j]即可。
2.dist[j] == w[i] + distance
这种情况是遍历到等于以确定最短路的情况,这时的处理是
ans[j] += ans[v];
这种时候就不需要覆盖了,直接加上即可
3.dist[j] < w[i] + distance
可以直接抛弃这种情况,因为要求的是最短路径的数量,这种时候的dist[j]不是最短路。
最后贴上代码
ans[j] = ans[ver```
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Os")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("Og")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <ll , ll> pii;
typedef priority_queue <ll ,vector<ll> ,greater<ll> > xiao;
typedef priority_queue <ll ,vector<ll> ,less<ll> > da;
const int N=1e6 + 10,M = 4e6 + 5,inf = 0x3f3f3f3f,mod = 1e5 + 3;
const ull P = 131;
int h[N],e[M],ne[M],idx;
int ans[N],dist[N];
bool st[N];
void add(int a,int b)
{
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dijkstra()
{
memset(dist , inf , sizeof dist);
dist[1] = 0;
ans[1] = 1;
priority_queue <pii , vector<pii> , greater<pii> > heap;
heap.push({0 , 1});
while(heap.size())
{
auto t = heap.top();
heap.pop();
int u = t.first,v = t.second;
for(int i = h[v] ; i != -1 ; i = ne[i])
{
int j = e[i];
if(dist[j] == u + 1)
{
ans[j] += ans[v];
ans[j] %= mod;
}else if(dist[j] > u + 1)
{
dist[j] = u + 1;
heap.push({dist[j] , j});
ans[j] = ans[v];
ans[j] %= mod;
}
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0),cout.tie(0);
memset(h , -1 , sizeof h);
int n,m;
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
add(a , b);
add(b , a);
}
dijkstra();
for(int i = 1 ; i <= n ; i++)
{
cout<<ans[i] % mod<<"\n";
}
}