1. 程式人生 > >uva 11367 (Dijkstra+DP)

uva 11367 (Dijkstra+DP)

優先隊列 ans ID oss 起點 amp 容量 汽車 push_back

題意:一輛汽車在一張無向圖中開告訴你每個城市加油的費用。每次給q個查詢(起點,終點,油箱容量)問你最小花費是多少。

思路:一道Dijkstra狀態的題目。在這種最短路問題中一維的dis數組記錄的信息往往不能很好的解決問題,所以我們要給dis數組增加維數來使每個狀態唯一。這其實就是結合了動態規劃的思想,然後考慮每個狀態能怎麽轉移(這其實就是單個結點從隊列中彈出來的處理過程)

對於這道題,我們增加一維表示當前汽車的剩油量,然後每個狀態有兩種轉移方式1.直接開去下一個節點2.一格一格加油。最後統計一下目標節點所有油量的花費最小值,就能得出答案了。

 1 #include <cstdio>
 2
#include <cstring> 3 #include <vector> 4 #include <queue> 5 #include <algorithm> 6 7 using namespace std; 8 9 typedef pair<int,int> pii; 10 const int maxn = 1005; 11 const int maxm = 105; 12 const int inf = 0x3f3f3f3f; 13 14 int N,M,P[maxn],D[maxn][maxm];//
到i點油量為j時的花費 15 int vis[maxn][maxm]; 16 vector<pii> G[maxn]; 17 18 struct State 19 { 20 int u,l,d;//地點,油量,花費 21 State(int u=0,int l=0,int d=0):u(u),l(l),d(d){} 22 bool operator <(const State & a) const {return d > a.d;}//優先隊列從小到大,默認大根堆 23 }; 24 25 void init() 26 { 27
for (int i = 0; i < N; i++) { 28 G[i].clear(); 29 scanf("%d", &P[i]); 30 } 31 32 int u, v, w; 33 while (M--) { 34 scanf("%d%d%d", &u, &v, &w); 35 G[u].push_back(make_pair(v, w)); 36 G[v].push_back(make_pair(u, w)); 37 } 38 } 39 40 int dijkstra(int s,int e,int c) 41 { 42 memset(D, inf, sizeof(D)); 43 memset(vis, 0, sizeof(vis)); 44 45 D[s][0] = 0; 46 priority_queue<State> q; 47 q.push(State(s,0,D[s][0])); 48 49 while(!q.empty()) 50 { 51 State cur=q.top(); q.pop(); 52 53 int u = cur.u, l=cur.l; 54 if(vis[u][l])continue; 55 vis[u][l]=1; 56 57 for(int i=0;i<G[u].size();i++) 58 { 59 int v=G[u][i].first, w=G[u][i].second; 60 if(w>l)continue; 61 if(D[v][l-w]>D[u][l]) 62 { 63 D[v][l-w]=D[u][l]; 64 q.push(State(v,l-w,D[v][l-w])); 65 } 66 } 67 68 if(l < c && D[u][l+1]>D[u][l]+P[u])//每次加一升 69 { 70 D[u][l+1]=D[u][l]+P[u]; 71 q.push(State(u,l+1,D[u][l+1])); 72 } 73 } 74 /* 75 int ret = inf; 76 for (int i = 0; i <= c; i++) 77 ret = min(ret, D[e][i]); 78 return ret; 79 */ 80 return D[e][0]; 81 } 82 83 int main () { 84 while (scanf("%d%d", &N, &M) == 2) { 85 init(); 86 int q, s, e, c; 87 scanf("%d", &q); 88 while (q--) { 89 scanf("%d%d%d", &c, &s, &e); 90 int ans = dijkstra(s, e, c); 91 if (ans == inf) printf("impossible\n"); 92 else printf("%d\n", ans); 93 } 94 } 95 return 0; 96 }

uva 11367 (Dijkstra+DP)