题目描述
给出一个 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;
}