P4009 汽車加油行駛問題

2021-10-16 13:02:53 字數 1633 閱讀 9972

看了很多題解,無論什麼解法都繞不開分層圖

在本題中加滿油的車每次可以移動k步,那麼我們就可以建立乙個k+1層的分層圖,表示汽車油量k的狀態(油量0…k),然後根據題目要求建圖

首先我們規定(k從1開始)第k層第i行第j列點編號為(k-1) * n * n + (i-1) * n + j

首先我們從第k層(i,j)建立一條邊到第k+1層(i,j),邊權為0,相當於車原地不動(其實這一步可有可無)

然後肯定是否到達油站來詳細分析:

當到達油站時,油會加滿,所以無論當前為哪一層都要指向第一層指向乙個邊,邊權為a(即加油費)。然後從第一層的(i,j)向第二層的四個方向指向邊,因為當i和j減少時要化為b,所以指向(i-1,j)和(i,j-1)時邊權為b,另外兩個(i+1,j)和(i,j+1)邊權為0,當然要注意當前點是否在圖的邊緣,以防止越界

當沒到油站時,我們要向下一層的四個方向指向邊,然後我們要模擬建立油站的情況,該點所有層均要向第一層生成乙個有向邊,邊權為建立油站的費用+加油的費用(即a+c)

然後跑最大流或者spfa都可以

結合**分析分析

#include

#include

#include

#include

using

namespace std;

const

int inf=

2e9;

int n,k,p,b,c,cnt;

int head[

350005

],dis[

350005

],q[

900005];

bool vis[

350005

],oil;

struct nodea[

900005];

void

add(

int x1,

int y1,

int z1,

int x2,

int y2,

int z2,

int dis)

; head[u]

=cnt;

}void

spfa()

}}}}

intmain()

if(oil)

if(i

add(i,j,

1,i+

1,j,2,

0);if

(jadd(i,j,

1,i,j+1,

2,0)

;if(i>1)

add(i,j,

1,i-

1,j,

2,b);if

(j>1)

add(i,j,

1,i,j-1,

2,b);}

else

for(

int l=

2;l<=k+1;

++l)}}

}spfa()

;int ans=inf;

for(

int i=

1;i<=k+1;

++i) ans=

min(ans,dis[n*n*i]);

printf

("%d\n"

,ans)

;return0;

}

P4009 汽車加油行駛問題

題意 給定乙個 n n n n 的方形網格,設其左上角為起點,座標為 1,1 1,1 x x 軸向右為正,y y 軸向下為正,每個方格邊長為 1 1 一輛汽車從起點出發駛向右下角終點 n,n n,n 在若干個網格交叉點處,設定了油庫。汽車在行駛過程中應遵守如下規則 汽車只能沿網格邊行駛,裝滿油後能行...

P4009 汽車加油行駛問題

傳送門 n和k都不大 可以跑分層圖 設dis i j k 表示從起點到座標為 i j 的點,還剩下可以跑 k 步的油時的最少花費 然後用 dijkstra 跑分層圖 走下一步時就分開來討論每種可能的操作 但是一定要注意每種操作的順序 先走,然後考慮走到的這點要不要設加油站,再考慮走到的這點有沒有加油...

洛谷P4009 汽車加油行駛問題

給定乙個 n times nn n 的方形網格,設其左上角為起點 座標 1,1 1,1 xx 軸向右為正,yy 軸向下為正,每個方格邊長為 11 如圖所示。一輛汽車從起點 出發駛向右下角終點 其座標為 n,n n,n 在若干個網格交叉點處,設定了油庫,可供汽車在行駛途中加油。汽車在行駛過程中應遵守如...