Luogu P1144 最短路计数

Description:

给出一个N个顶点M条边的无向无权图,顶点编号为1−N。问从顶点11开始,到其他每个点的最短路有几条。只需要输出 ans mod 100003 后的结果即可。如果无法到达顶点i则输出0。

Analysis:

因为所有的边权都为1,所以一个点的最短路就相当于是它在BFS搜索树中的深度。一个点最短路一定经过了一个层数比它少一的结点(否则不是最短路)。所以用每个相邻且层数比当前结点层数少一的点更新当前点的路径跳数即可。

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define N 1000010
using namespace std;
const int mod = 100003;
struct edge{
	int to,next,w;
}e[N << 1];
int head[N],dep[N],vis[N],num_edge,n,m;
int cnt[N];
void add(int a,int b)
{
	e[++num_edge].next = head[a];
	e[num_edge].to = b;
	e[num_edge].w = 1;
	head[a] = num_edge;
}
void solve()
{
	queue<int> Q;
	Q.push(1);
	cnt[1] = 1;
	memset(dep,0x3f3f3f3f,sizeof(dep));
	dep[1] = 0;
	while(!Q.empty())
	{
		int u = Q.front();Q.pop();
		vis[u] = 1;
		for(int i = head[u];i;i = e[i].next)
		{
			int v = e[i].to;
			if(!vis[v])
			{
				vis[v] = 1;
				dep[v] = dep[u] + 1;
				Q.push(v);
			}
			if(dep[v] == dep[u] + 1){
				cnt[v] = (cnt[v]%mod + cnt[u]%mod)%mod;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			}
		}
	}
	for(int i = 1;i <= n;++i) printf("%d
",cnt[i]);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= m;++i)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		add(a,b);
		add(b,a);
	}
	solve();
	return 0;
}

岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/10799473.html