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 (最小费用流)

uva 10806 Dijkstra, Dijkstra. (最小费最大流)

训练指南 UVA - 11374(最短路Dijkstra + 记录路径 + 模板)