题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1−N。问从顶点1开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行2个正整数x,y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
共N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出ansmod100003后的结果即可。如果无法到达顶点i则输出0。
输入输出样例
输入样例#1: 复制
5 7 1 2 1 3 2 4 3 4 2 3 4 5 4 5
输出样例#1: 复制
1 1 1 2 4
说明
1到5的最短路有4条,分别为2条1−2−4−5和22条1−3−4−5(由于4−5的边有2条)。
对于20%的数据,N≤100;
对于60%的数据,N≤1000;
对于100%的数据,N<=1000000,M<=2000000。
这个题是最短路问题 求1到每个点有多少种最短路
代码:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define mod 100003
int cnt,n,m,x,y,dis[1000005],vis[1000005],head[4000005],ans[1000005];
struct node
{
int sum,now;
bool operator < (const node&x) const
{
return sum>x.sum;
}
};
priority_queue<node>q;
struct aa
{
int x,y,sum,next;
}e[4000005];
void add(int x,int y,int sum)
{
cnt++;
e[cnt].x=x;
e[cnt].y=y;
e[cnt].sum=sum;
e[cnt].next=head[x];
head[x]=cnt;
}//邻接表
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
if(x==y) continue;
add(x,y,1);
add(y,x,1);
}
for(int i=1;i<=n;i++)
dis[i]=INF;
dis[1]=0;
ans[1]=1;
q.push((node){0,1});
while(!q.empty())
{
node x=q.top();
q.pop();
int u=x.now;
if(vis[u]) continue;
vis[u]=1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].y;
if(dis[v]>dis[u]+e[i].sum)
{
dis[v]=dis[u]+e[i].sum;
ans[v]=ans[u];//最短路更新了,所以之前的都不能要 到这个最短路只能从u来
q.push((node){dis[v],v});
}
else if(dis[v]==dis[u]+e[i].sum)//同样能到达v的最短路
{
ans[v]+=ans[u];//到v的最短路 可以从u来 所以加上ans[u]
ans[v]%=mod;
}
}
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<endl;
return 0;
}