1. 程式人生 > 實用技巧 >洛谷 P1144 最短路計數

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