洛谷 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;
}

posted @ 2020-11-03 18:39  Seaway-Fu  阅读(98)  评论(0编辑  收藏  举报