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

最短路計數 洛谷 1114 最短路

題目描述

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

分析

可以使用最短路。鬆弛的時候如果遇到沒有訪問過的則ans[v]=ans[u],如果遇到訪問過而且dis[v]==dis[u]+1,則將方案數累計入ans[v]。

記得取模

ans的初始值為0,起點為1。

code

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
#include<stack> #include<queue> #include<vector> using namespace std; struct arr{ int x,y,w,next; }edge[2000200]; int ans[1000200]; int ls[1000200]; int dis[1000200]; int v[1000200]; int n,m,s,t; int edge_m; struct cmp{ bool operator ()(int a,int b){ return dis[a]>dis[b]; } }; //優先佇列的定義。
void add(int x,int y,int w) { edge_m++; edge[edge_m]=(arr){x,y,w,ls[x]};ls[x]=edge_m; edge_m++; edge[edge_m]=(arr){y,x,w,ls[y]};ls[y]=edge_m; } int main() { scanf("%d%d",&n,&m); s=1; priority_queue<int,vector<int>,cmp> Q; memset(dis,63,sizeof(dis)); for
(int i=1;i<=m;i++) { int x,y,w; scanf("%d%d",&x,&y); w=1; add(x,y,w); } ans[s]=1; dis[s]=0; v[s]=1; Q.push(s); for (int ii=1;ii<=n;ii++) { int x=Q.top(); Q.pop(); for (int j=ls[x];j;j=edge[j].next) { if (dis[edge[j].y]>dis[x]+edge[j].w) { dis[edge[j].y]=dis[x]+edge[j].w; ans[edge[j].y]=ans[x]; if (!v[edge[j].y]) { v[edge[j].y]=1; Q.push(edge[j].y); } } else if (dis[edge[j].y]==dis[x]+edge[j].w) ans[edge[j].y]=(ans[edge[j].y]+ans[x])%100003; } } for (int ii=1;ii<=n;ii++) printf("%d\n",ans[ii]%100003); }