• 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
    ");
    92             else printf("%d
    ", ans);
    93         }
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    3月9号作业
    7、循环之while循环和深浅copy
    6、可变不可变类型和运算符以及流程控制之if判断
    5、垃圾回收机制与用户交互以及运算符
    作业3月5号
    3月4号作业
    4、语法之变量以及基本数据类型
    3、Python介绍
    2、计算机基础详解
    五、流程控制值if...else
  • 原文地址:https://www.cnblogs.com/demian/p/9033681.html
Copyright © 2020-2023  润新知