uva 11367 (Dijkstra+DP)

题意:一辆汽车在一张无向图中开告诉你每个城市加油的费用。每次给q个查询(起点,终点,油箱容量)问你最小花费是多少。

思路:一道Dijkstra状态的题目。在这种最短路问题中一维的dis数组记录的信息往往不能很好的解决问题,所以我们要给dis数组增加维数来使每个状态唯一。这其实就是结合了动态规划的思想,然后我们在考虑每个状态能怎么转移(这其实就是单个结点从队列中弹出来的处理过程)这样一道题就做出来了。

对于这道题,我们增加一维表示当前汽车的剩油量,然后每个状态有两种转移方式1.直接开去下一个节点2.加一格油。最后统计一下目标节点所有油量的花费最小值,就能得出答案了。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <stack>
 9 #include <vector>
10 #define MP(a, b) make_pair(a, b)
11 #define PB(a) push_back(a)
12 
13 using namespace std;
14 
15 typedef long long ll;
16 typedef struct {int p, o;}S;
17 typedef pair<int, S> pis;
18 typedef pair<int, int> pii;
19 typedef pair<unsigned int, unsigned int> puu;
20 typedef pair<int ,double> pid;
21 typedef pair<ll, int> pli;
22 
23 const int INF = 0x3f3f3f3f;
24 const double eps = 1e-6;
25 const int LEN = 1010;
26 vector<pii> Map[LEN];
27 int n, m, oil[LEN], dis[LEN][110], vis[LEN][110], minans;
28 struct cmp{
29     bool operator() (pis a, pis b){return a.first > b.first;}
30 };
31 
32 inline S MS(int a, int b){S ret; ret.p = a, ret.o = b;return ret;}
33 
34 void read(int &ret)
35 {
36     char c;
37     while((c = getchar())<'0' || c>'9');
38     ret = 0;
39     while(c>='0' && c<='9'){
40         ret = ret*10+(c-'0');
41         c = getchar();
42     }
43 }
44 
45 void Dijkstra(int s, int e, int lv)
46 {
47     priority_queue<pis, vector<pis>, cmp> q;
48     memset(vis, 0, sizeof vis);
49     memset(dis, 0x3f, sizeof dis);
50     dis[s][0] = 0;minans = INF;
51     q.push(MP(dis[s][0], MS(s,0)));
52     while(!q.empty()){
53         pis nvex = q.top(); q.pop();
54         S ns = nvex.second;
55         int nv = ns.p, no = ns.o;
56         if(vis[nv][no])continue;
57         vis[nv][no] = 1;
58 
59         if(no+1<=lv && dis[nv][no+1] > dis[nv][no] + oil[nv]){
60             dis[nv][no+1] = dis[nv][no] + oil[nv];
61             q.push(MP(dis[nv][no+1], MS(nv,no+1)));
62         }
63         for(int i=0; i<Map[nv].size(); i++){
64             int x = Map[nv][i].first, y = Map[nv][i].second;
65             if(y <= no && dis[x][no-y] > dis[nv][no]){
66                 dis[x][no-y] = dis[nv][no];
67                 q.push(MP(dis[x][no-y], MS(x,no-y)));
68             }
69         }
70     }
71 }
72 
73 int main()
74 {
75 //    freopen("in.txt", "r", stdin);
76 
77     int a, b, v, q, ans;
78     while(scanf("%d%d", &n, &m)!=EOF){
79         for(int i=0; i<n; i++)Map[i].clear();
80         for(int i=0; i<n; i++)read(oil[i]);
81         for(int i=0; i<m; i++){
82             read(a);read(b);read(v);
83             Map[a].PB(MP(b, v));
84             Map[b].PB(MP(a, v));
85         }
86         read(q);
87         for(int i=0; i<q; i++){
88             read(v);read(a);read(b);
89             Dijkstra(a, b, v);
90             ans = INF;
91             for(int i=0; i<=v; i++)ans = min(ans, dis[b][i]);
92             if(ans!=INF)printf("%d\n", ans);
93             else puts("impossible");
94         }
95     }
96     return 0;
97 }
View Code

 

posted @ 2014-01-13 21:29  张小豪  阅读(416)  评论(0编辑  收藏  举报