1. 程式人生 > >洛谷 P1144 最短路計數

洛谷 P1144 最短路計數

-- 多少 pop fine www pty class 接下來 輸出格式

題目描述

給出一個N個頂點M條邊的無向無權圖,頂點編號為1~N。問從頂點1開始,到其他每個點的最短路有幾條。

輸入輸出格式

輸入格式:

輸入第一行包含2個正整數N,M,為圖的頂點數與邊數。

接下來M行,每行兩個正整數x, y,表示有一條頂點x連向頂點y的邊,請註意可能有自環與重邊。

輸出格式:

輸出包括N行,每行一個非負整數,第i行輸出從頂點1到頂點i有多少條不同的最短路,由於答案有可能會很大,你只需要輸出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

說明

1到5的最短路有4條,分別為2條1-2-4-5和2條1-3-4-5(由於4-5的邊有2條)。

對於20%的數據,N ≤ 100;

對於60%的數據,N ≤ 1000;

對於100%的數據,N<=1000000,M<=2000000。

spfa

屠龍寶刀點擊就送

#include <cstdio>
#include <vector>
#include <queue>
#define N 1000500
#define MOD 100003

using std::vector;
using
std::queue; vector<int>edge[N]; bool vis[N]; int n,m,sum[N],dis[N]; void spfa(int s) { for(int i=1;i<=n;++i) vis[i]=0,dis[i]=N; dis[s]=0;sum[s]=1; queue<int>q; q.push(s); for(int now=q.front();!q.empty();q.pop(),now=q.front()) { vis[now]=1;
for(int i=0;i<edge[now].size();++i) { int v=edge[now][i]; if(dis[v]>dis[now]+1) { dis[v]=dis[now]+1; if(!vis[v]) { vis[v]=1; q.push(v); } sum[v]=sum[now]; } else if(dis[v]==dis[now]+1) sum[v]=(sum[v]+sum[now])%MOD; } } } int main() { scanf("%d%d",&n,&m); for(int x,y;m--;) { scanf("%d%d",&x,&y); edge[x].push_back(y); edge[y].push_back(x); } spfa(1); for(int i=1;i<=n;++i) printf("%d\n",sum[i]); return 0; }

洛谷 P1144 最短路計數