1. 程式人生 > 實用技巧 >二維spfa模板

二維spfa模板

題目描述

  • 編號為1-N的N座城鎮用若干僅供單向行駛的道路相連,每條道路上均有兩個引數:道路長度(lenth)和在該條道路上行駛的費用(cost)。
BOB準備從城鎮1出發到達城鎮N,但他目前只有W的錢,為此,你需要幫助他尋找一條從城鎮1到城鎮N在他能支付的前提下的一條最短路線。

輸入格式


  • W,N,M(N為城鎮數目,2<=N<=100,M為道路條數,W為錢的數目
  • 隨後的M行每行為一條道路的資訊,包含4個數值(u,v,w,cost),表示從城鎮u到v有一條長度為cost的單向道路,經過這條道路需要花費 cost。(1<=u,v<=N,1<=w<=100,1<=cost<=100)

輸出格式

輸出最短長度,若無解,則輸出“NO”;

樣例

樣例輸入

5 6 7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

樣例輸出

11
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100+10,maxm=10000+10,inf=0x3f3f3f3f;
 4     int w,n,m;
 5 struct Edge{
 6     int to,next,lenth,money;
7 }e[maxm]; 8 int head[maxn],tot=0; 9 void Insert(int a,int b,int c,int d){ 10 e[++tot].to=b; 11 e[tot].lenth=c; 12 e[tot].money=d; 13 e[tot].next=head[a]; 14 head[a]=tot; 15 } 16 int d[maxn][1000+10]; 17 void spfa(int x){ 18 queue< pair<int,int> > q; 19 int vis[maxn][1000
+10]; 20 memset(d,0x3f,sizeof(d)); 21 memset(vis,0,sizeof(vis)); 22 q.push(make_pair(x,0)); 23 vis[x][0]=1; 24 d[x][0]=0; 25 while(!q.empty()){ 26 pair<int,int> now=q.front(); 27 q.pop(); 28 int u=now.first; 29 int s=now.second; 30 vis[u][s]=0; 31 for(int i=head[u];i;i=e[i].next){ 32 int v=e[i].to; 33 if(s+e[i].money>w) continue; 34 if(d[v][s+e[i].money]>d[u][s]+e[i].lenth){ 35 d[v][s+e[i].money]=d[u][s]+e[i].lenth; 36 if(!vis[v][s+e[i].money]){ 37 vis[v][s+e[i].money]=1; 38 q.push(make_pair(v,s+e[i].money)); 39 } 40 } 41 } 42 } 43 } 44 int main(){ 45 scanf("%d%d%d",&w,&n,&m); 46 for(int i=1;i<=m;i++){ 47 int u,v,l,cost; 48 scanf("%d%d%d%d",&u,&v,&l,&cost); 49 Insert(u,v,l,cost); 50 } 51 spfa(1); 52 int ans=inf; 53 for(int i=0;i<=w;i++){ 54 ans=min(ans,d[n][i]); 55 } 56 if(ans==inf) printf("NO\n"); 57 else printf("%d\n",ans); 58 return 0; 59 }
View Code