uva 11367 (Dijkstra+DP)
Posted Point
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva 11367 (Dijkstra+DP)相关的知识,希望对你有一定的参考价值。
题意:一辆汽车在一张无向图中开告诉你每个城市加油的费用。每次给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)的主要内容,如果未能解决你的问题,请参考以下文章
训练指南 UVA - 10917(最短路Dijkstra + 基础DP)
UVa 1001 Say Cheese (Dijkstra)
UVa 12661 Funny Car Racing (dijkstra)
UVa 10806 Dijkstra, Dijkstra (最小费用流)