1. 程式人生 > >洛谷 P4009 汽車加油行駛問題 題解

洛谷 P4009 汽車加油行駛問題 題解

網路流24題?費用流?不存在的

tag都是騙人的

首先看題,仔細想想,這不就是一個最短路嗎?

從 (1,1) 往 (n,n) 跑最短路,以 dis[x][y][res] 來記錄當位於 (x,y) 時還能再跑 res 條邊的最小花費

每次擴充套件節點的時候更新加油的花費, 注意當(x,y) 有油庫時強制加油,沒有時可不加

最後 for i from 0 to k 統計 dis[n][n][i] 的最小值,即為答案

實現細節見程式碼

Tips:程式碼中含有 __gnu_pbds::priority_queue 與 std::tuple ,可能引起強烈不適,請謹慎食用

 1 #ifndef ONLINE_JUDGE
 2 #define _EXT_ENC_FILEBUF_H 1
 3 #define _EXT_CODECVT_SPECIALIZATIONS_H 1
 4 #endif // ONLINE_JUDGE
 5 #include<bits/stdc++.h>
 6 #include<bits/extc++.h>
 7 using namespace
std; 8 typedef tuple<int,int,int> pit; // x, y, res 9 constexpr int fx[5][2]={{0,0},{1,0},{0,-1},{-1,0},{0,1}}; 10 int n,K,A,B,C,ans=numeric_limits<int>::max(); 11 int dis[150][150][20]; 12 bool in[150][150][20],oil[150][150]; 13 struct cmp{bool operator()(pit a,pit b) 14 {return dis[get<0>(a)][get
<1>(a)][get<2>(a)]>dis[get<0>(b)][get<1>(b)][get<2>(b)];}}; 15 __gnu_pbds::priority_queue<pit,cmp,__gnu_pbds::pairing_heap_tag> q; 16 void SPFA(); 17 int main() 18 { 19 scanf("%d%d%d%d%d",&n,&K,&A,&B,&C); 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=n;j++){ 22 int col; 23 scanf("%d",&col); 24 oil[i][j]=(col==1); 25 } 26 SPFA(); 27 for(int i=0;i<=K;i++) 28 ans=min(ans,dis[n][n][i]); 29 printf("%d",ans); 30 } 31 void SPFA() 32 { 33 memset(dis,0x7f,sizeof(dis)); 34 dis[1][1][K]=0; 35 in[1][1][K]=true; 36 q.push(make_tuple(1,1,K)); 37 while(!q.empty()){ 38 pit now=q.top(); 39 q.pop(); 40 int x=get<0>(now),y=get<1>(now),res=get<2>(now); 41 in[x][y][res]=false; 42 if(oil[x][y]&&res!=K){ 43 if(dis[x][y][K]>dis[x][y][res]+A){ 44 dis[x][y][K]=dis[x][y][res]+A; 45 if(!in[x][y][K]){ 46 q.push(make_tuple(x,y,K)); 47 in[x][y][K]=true; 48 } 49 } 50 continue; 51 } 52 if(dis[x][y][K]>dis[x][y][res]+A+C){ 53 dis[x][y][K]=dis[x][y][res]+A+C; 54 if(!in[x][y][K]){ 55 q.push(make_tuple(x,y,K)); 56 in[x][y][K]=true; 57 } 58 } 59 if(res<=0) continue; 60 for(int i=1;i<=4;i++){ 61 int xi=x+fx[i][0],yi=y+fx[i][1]; 62 if(xi<1||xi>n||yi<1||yi>n) continue; 63 int cost=(xi<x||yi<y)?B:0; 64 if(dis[xi][yi][res-1]>dis[x][y][res]+cost){ 65 dis[xi][yi][res-1]=dis[x][y][res]+cost; 66 if(!in[xi][yi][res-1]){ 67 q.push(make_tuple(xi,yi,res-1)); 68 in[xi][yi][res-1]=true; 69 } 70 } 71 } 72 } 73 }
View Code