1. 程式人生 > >「LuoguP1144」 最短路計數(dijkstra

「LuoguP1144」 最短路計數(dijkstra

題目描述

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

輸入輸出格式

輸入格式:

 

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

接下來MM行,每行22個正整數x,yx,y,表示有一條頂點xx連向頂點yy的邊,請注意可能有自環與重邊。

 

輸出格式:

 

NN行,每行一個非負整數,第ii行輸出從頂點11到頂點ii有多少條不同的最短路,由於答案有可能會很大,你只需要輸出ans \bmod 100003ansmod100003後的結果即可。如果無法到達頂點ii則輸出00。

 

輸入輸出樣例

輸入樣例#1:  複製
5 7
1 2
1 3
2 4
3 4
2 3
4 5
4 5
輸出樣例#1:  複製
1
1
1
2
4

說明

11到55的最短路有44條,分別為22條1-2-4-51245和22條1-3-4-51345(由於4-545的邊有22條)。

對於20\%20%的資料,N ≤ 100N100;

對於60\%60%的資料,N ≤ 1000N1000;

對於100\%100%的資料,N<=1000000,M<=2000000N<=1000000,M<=2000000。

題解

算是最短路的小技巧?

if(dis[to]>dis[x]+1)ans[to]=ans[x];
else if(dis[to]==dis[x]+1)ans[to]+=ans[x];

在dijkstra的同時順便維護,這樣就可以了。

不是很敢用spfa。

然後注意一下這道題是無向圖要建雙向邊就好了。

 1 /*
 2 qwerta 
 3 P1144 最短路計數 Accepted 
 4 100
 5 程式碼 C++,1.05KB
 6 提交時間 2018-11-05 22:20:55
 7 耗時/記憶體 247ms, 9120KB
 8 */
 9 #include<iostream>
10
#include<cstring> 11 #include<cstdio> 12 #include<queue> 13 using namespace std; 14 struct emm{ 15 int e,f; 16 }a[4000003]; 17 int h[1000003]; 18 int tot=0; 19 void con(int x,int y) 20 { 21 a[++tot].f=h[x]; 22 h[x]=tot; 23 a[tot].e=y; 24 a[++tot].f=h[y]; 25 h[y]=tot; 26 a[tot].e=x; 27 return; 28 } 29 int d[1000003]; 30 int s[1000003]; 31 struct ahh{ 32 int nod,v; 33 }; 34 struct cmp{ 35 bool operator()(ahh qaq,ahh qwq){ 36 return qaq.v>qwq.v; 37 }; 38 }; 39 priority_queue<ahh,vector<ahh>,cmp>q; 40 bool sf[1000003]; 41 const int mod=100003; 42 int main() 43 { 44 int n,m; 45 scanf("%d%d",&n,&m); 46 for(int i=1;i<=m;++i) 47 { 48 int x,y; 49 scanf("%d%d",&x,&y); 50 con(x,y); 51 } 52 memset(d,127,sizeof(d)); 53 d[1]=0;s[1]=1; 54 q.push((ahh){1,0}); 55 while(!q.empty()) 56 { 57 int x; 58 do{x=q.top().nod;q.pop();}while(sf[x]&&!q.empty()); 59 sf[x]=1; 60 for(int i=h[x];i;i=a[i].f) 61 if(!sf[a[i].e]) 62 { 63 if(d[a[i].e]>d[x]+1) 64 { 65 d[a[i].e]=d[x]+1; 66 s[a[i].e]=s[x]; 67 q.push((ahh){a[i].e,d[a[i].e]}); 68 } 69 else if(d[a[i].e]==d[x]+1) 70 { 71 s[a[i].e]+=s[x]; 72 s[a[i].e]%=mod; 73 } 74 } 75 } 76 for(int i=1;i<=n;++i) 77 printf("%d\n",s[i]%mod); 78 return 0; 79 }