题目描述
给出一个N个顶点M条边的无向无权图,顶点编号为1-N。问从顶点1开始,到其他每个点的最短路有几条。
输入输出格式
输入格式:
第一行包含2个正整数N,M,为图的顶点数与边数。
接下来M行,每行2个正整数x,y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边。
输出格式:
共N行,每行一个非负整数,第ii行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans mod 100003后的结果即可。如果无法到达顶点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
【解题思路】:
在dijkstra函数内定义一个node类型的变量,然后每次用这个变量提取队首元素,统计这个点的前驱到这个点的路径是否等于它的最短路径,然后一边算一边模即可。
【AC代码】:
#include<bits/stdc++.h>
#define M(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define Mod 100003
using namespace std;
inline void read(int &x){
char ch=getchar(),c=ch;
x=0;
while(ch<'0' || ch>'9'){
c=ch;
ch=getchar();
}
while(ch>='0' && ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
if(c=='-')x=-x;
}
int n,m,dis[1000005],head[1000005],s,js[1000005],num;
struct Edge
{
int v,w,nxt;
}edge[2000005];
inline void ct(int u,int v,int w)
{
edge[++num].v=v;
edge[num].w=w;
edge[num].nxt=head[u];
head[u]=num;
}
struct node
{
int x,y;
bool operator < (const node &a) const
{
return y>a.y;
}
};
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
priority_queue<node>q;
js[1]=1;
q.push((node){1,0});
node a;
while(!q.empty()){
a=q.top();
int u=a.x,d=a.y;
q.pop();
if(d!=dis[u])continue;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(d+edge[i].w==dis[v])js[v]=(js[u]+js[v])%Mod;
if((dis[v]>dis[u]+edge[i].w)){
dis[v]=dis[u]+edge[i].w;
js[v]=js[u];
q.push((node){v,dis[v]});
}
}
}
}
int main()
{
read(n),read(m);
for(int i=1,u,v;i<=m;++i)
{
read(u),read(v);
ct(u,v,1);
ct(v,u,1);
}
dijkstra();
for(int i=1;i<=n;++i)cout<<js[i]<<'\n';
cout<<'\n';
return 0;
}