洛谷P1144 最短路计数

题目描述

给出一个 NN 个顶点 MM 条边的无向无权图,顶点编号为 1\sim N1∼N。问从顶点 11 开始,到其他每个点的最短路有几条。

输入格式

第一行包含 22 个正整数 N,MN,M,为图的顶点数与边数。

接下来 MM 行,每行 22 个正整数 x,yx,y,表示有一条由顶点 xx 连向顶点 yy 的边,请注意可能有自环与重边。

输出格式

共 NN 行,每行一个非负整数,第 ii 行输出从顶点 11 到顶点 ii 有多少条不同的最短路,由于答案有可能会很大,你只需要输出 ans \bmod 100003ansmod100003 后的结果即可。如果无法到达顶点 ii 则输出 00。

输入输出样例

输入 #1复制

5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5

输出 #1复制

1
1
1
2
4

说明/提示

11 到 55 的最短路有 44 条,分别为 22 条 1\to 2\to 4\to 51→2→4→5 和 22 条 1\to 3\to 4\to 51→3→4→5(由于 4\to 54→5 的边有 22 条)。

对于 20\%20% 的数据,1\le N \le 1001≤N≤100;
对于 60\%60% 的数据,1\le N \le 10^31≤N≤103;
对于 100\%100% 的数据,1\le N\le10^61≤N≤106,1\le M\le 2\times 10^61≤M≤2×106。

思路:由于是酷暑时期,头脑晕眩,一开始看到题目没有发现是无权的,在那里想了很久,最后知道无权后很明显一个bfs就是找最短路顺便还有条数,具体如下。但是还是交了很多遍才过,第一次是没有发现到无向图,第二次是没有发现到要mod100003,而还是再交了一次,由于第三次提交的时候又是有向图哈哈哈。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5,mod=100003;
bool vis[maxn];
ll cnt[maxn]={0,1};
vector<int> edg[maxn];
int stp[maxn];//更新一次,后面就是判断用的,只有步数等于更新时候的步数才能加cnt 
void bfs()//可能有自环和重边 
{
	memset(stp,-1,sizeof stp);
	memset(vis,0,sizeof vis);
	stp[1]=0;
	queue<int> q;
	q.push(1);
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(auto v:edg[u])
		{
			if(stp[v]==-1||stp[v]==stp[u]+1)
			{
				stp[v]=stp[u]+1;
				cnt[v]=(cnt[v]+cnt[u])%mod;
				if(!vis[v])q.push(v);
				vis[v]=1;
			}
		}
	}
}
int main()
{
	ios_base::sync_with_stdio(false),cin.tie(nullptr);
	int n,m;
	cin>>n>>m;
	while(m--)
	{
		int u,v;
		cin>>u>>v;
		edg[u].push_back(v);
		edg[v].push_back(u);
	}
	bfs();
	for(int i=1;i<=n;i++)cout<<cnt[i]<<"\n";
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值