1. 程式人生 > >洛谷 1144_最短路計數_spfa

洛谷 1144_最短路計數_spfa

題目描述

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

思路

因為是無權邊,所以第一個走到的肯定是最短的,然後在spfa中開一個記錄的陣列,每次走到一個路程等於它的就加上來的那個點有多少種方法
O(KE)

#include <stdio.h>
#include <queue>
#define maxn 2000001
#define mod 100003
using namespace std;
int l=0;
struct arr 
{ 
    int x,y,w,next; 
};
arr edge[maxn];
int
state[maxn],ls[maxn],f[maxn]; bool exits[maxn]; int spfa() { int i; queue <int> t; t.push(1); state[1]=0; exits[1]=true; do { int tt=t.front(); t.pop(); i=ls[tt]; while (i!=0) { if (state[edge[i].x]+edge[i].w<=state[edge[i].y]) { f[edge[i].y]+=1
*f[edge[i].x]; f[edge[i].y]%=mod; state[edge[i].y]=state[edge[i].x]+edge[i].w; if (exits[edge[i].y]==false) { t.push(edge[i].y); exits[edge[i].y]=true; } } i=edge[i].next; } exits[tt]=false
; } while (!t.empty()); } int main() { int j,k,n,m,s; scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { l++; int x,y; scanf("%d%d",&x,&y); edge[l].x=x; edge[l].y=y; edge[l].w=1; edge[l].next=ls[edge[l].x]; ls[edge[l].x]=l; l++; edge[l].x=y; edge[l].y=x; edge[l].w=1; edge[l].next=ls[edge[l].x]; ls[edge[l].x]=l; } for (int i=1;i<maxn;i++) state[i]=0xfffffff; f[1]=1; spfa(); for (int i=1;i<=n;i++) printf("%d\n",f[i]); }