P1144 最短路计数

213 阅读2分钟

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"; 
	}
}