题目来源:
https://www.luogu.org/problemnew/show/P1144
题目描述:
题目描述
给出一个NN个顶点MM条边的无向无权图,顶点编号为1-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-2-4-51−2−4−5和22条1-3-4-51−3−4−5(由于4-54−5的边有22条)。
对于20\%20%的数据,N ≤ 100N≤100;
对于60\%60%的数据,N ≤ 1000N≤1000;
对于100\%100%的数据,N<=1000000,M<=2000000N<=1000000,M<=2000000。
解题思路:
裸的最短路计数,套个板就行,注意要mod。
代码:
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
vector<pair<int,int> >E[1000005];
bool vis[1000005];
int dis[1000005],ans[1000005];
int main()
{
memset(dis,inf,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
E[a].push_back(make_pair(b,1));
E[b].push_back(make_pair(a,1));
}
queue<int>q;
dis[1]=0;
ans[1]=1;
q.push(1);
vis[1]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
vis[now]=0;
for(int i=0;i<E[now].size();i++)
{
int v=E[now][i].first;
if(dis[v]>dis[now]+E[now][i].second)
{
dis[v]=dis[now]+E[now][i].second;
ans[v]=(ans[now])%100003;
if(vis[v])continue;
vis[v]=1;
q.push(v);
}
else if(dis[v]==dis[now]+E[now][i].second){
ans[v]=(ans[now]+ans[v])%100003;
}
}
}
for(int i=1;i<=n;i++)
{
if(dis[i]!=inf)cout<<ans[i]<<endl;
else cout<<0<<endl;
}
return 0;
}