洛谷 P1144 最短路计数
洛谷 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。
题解:
最短路计数模板。
具体见:
代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int read()
{
int x=0,f=1;
char ch=nc();
while(ch<48||ch>57)
{
if(ch=='-')
f=-1;
ch=nc();
}
while(ch>=48&&ch<=57)
x=x*10+ch-48,ch=nc();
return x*f;
}
const int maxn=1e6+6;
const int mod=100003;
int n,e;
int tot,head[maxn],nxt[maxn<<2],to[maxn<<2];
void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
priority_queue<pair<int,int> >q;
int dist[maxn],cnt[maxn];
bool v[maxn];
void dijkstra()
{
memset(dist,127,sizeof(dist));
dist[1]=0;
cnt[1]=1;
q.push(make_pair(0,1));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(v[x])
continue;
v[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(dist[x]+1<dist[y])
{
dist[y]=dist[x]+1,cnt[y]=cnt[x];
q.push(make_pair(-dist[y],y));
}
else if(dist[x]+1==dist[y])
cnt[y]=(cnt[y]+cnt[x])%mod;
}
}
}
int main()
{
n=read();e=read();
for(int i=1;i<=e;i++)
{
int x,y;
x=read();y=read();
add(x,y);
add(y,x);
}
dijkstra();
for(int i=1;i<=n;i++)
printf("%d\n",cnt[i]%mod);
return 0;
}