• poj1724 ROADS


    题意:

    N个城市,编号1到N。城市间有R条单向道路。
    每条道路连接两个城市,有长度和过路费两个属性。
    Bob只有K块钱,他想从城市1走到城市N。问最短共需要走多长的路。如果到不了N,输出-1
    2<=N<=100
    0<=K<=10000
    1<=R<=10000
    每条路的长度 L, 1 <= L <= 100
    每条路的过路费T , 0 <= T <= 100

    思路:

    用d[i][j]表示从源点走到城市i并且花费为j的时候经过的最短距离。若在后续的搜索中,再次走到i时,如果总路费恰好为j,且此时的路径长度已经超过 d[i][j],则不必再走下去了。

    1.深搜+剪枝

    2.spfa+剪枝

    实现:

    1.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <cstring>
     6 using namespace std;
     7 
     8 const int MAXN = 100;
     9 const int MAXK = 10000;
    10 const int INF = 0x3f3f3f3f;
    11 
    12 struct node
    13 {
    14     int to, len, toll;
    15 };
    16 vector<node> G[MAXN + 5];
    17 int k, n, m, s, t, l, T, minLen = INF;
    18 
    19 bool vis[MAXN + 10];
    20 int d[MAXN + 5][MAXK + 5];
    21 
    22 void dfs(int now, int rem, int len)
    23 {
    24     if (now == n)
    25     {
    26         minLen = min(minLen, len);
    27         return;
    28     }
    29     for (int i = G[now].size() - 1; i >= 0; i--)
    30     {
    31         if (!vis[G[now][i].to] && rem >= G[now][i].toll)
    32         {
    33             if (d[G[now][i].to][rem - G[now][i].toll] <= 
    34                 len + G[now][i].len || len + G[now][i].len >= minLen)
    35                 continue;
    36             d[G[now][i].to][rem - G[now][i].toll] = len + G[now][i].len;
    37             dfs(G[now][i].to, rem - G[now][i].toll, len + G[now][i].len);
    38             vis[G[now][i].to] = false;
    39         }
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     cin >> k >> n >> m;
    46     for (int i = 0; i < m; i++)
    47     {
    48         cin >> s >> t >> l >> T;
    49         node tmp;
    50         tmp.to = t;
    51         tmp.len = l;
    52         tmp.toll = T;
    53         if (s != t)
    54             G[s].push_back(tmp);
    55     }
    56     memset(d, 0x3f, sizeof(d));
    57     vis[1] = true;
    58     dfs(1, k, 0);
    59     if (minLen == INF)
    60         puts("-1");
    61     else
    62         cout << minLen << endl;
    63     return 0;
    64 }

    2.

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <cstring>
      6 #include <queue>
      7 #include <functional>
      8 using namespace std;
      9 
     10 const int MAXN = 100;
     11 const int MAXK = 10000;
     12 const int INF = 0x3f3f3f3f;
     13 
     14 struct node
     15 {
     16     int to, len, toll;
     17 };
     18 vector<node> G[MAXN + 5];
     19 int k, n, m, s, t, l, T;
     20 
     21 struct co
     22 {
     23     int now, cost;
     24 };
     25 
     26 int d[MAXN + 5][MAXK + 5];
     27 int in[MAXN + 5][MAXK + 5];
     28 
     29 int spfa()
     30 {
     31     queue<co> q;
     32     co start;
     33     start.now = 1;
     34     start.cost = 0;
     35     q.push(start);
     36     in[1][0] = true;
     37     priority_queue<int, vector<int>, greater<int> > pq;
     38     pq.push(INF);
     39     while (!q.empty())
     40     {
     41         co tmp = q.front();
     42         q.pop();
     43         int now = tmp.now;
     44         int cost = tmp.cost;
     45         if (now == n)
     46         {
     47             pq.push(d[n][cost]);
     48         }
     49         in[now][cost] = false;
     50         for (int i = 0; i < G[now].size(); i++)
     51         {
     52             if (cost + G[now][i].toll <= k && 
     53                 d[now][cost] + G[now][i].len < d[G[now][i].to][cost + G[now][i].toll])
     54             {
     55                 d[G[now][i].to][cost + G[now][i].toll] = d[now][cost] + G[now][i].len;
     56                 if (d[G[now][i].to][cost + G[now][i].toll] >= pq.top())
     57                     continue;
     58                 if (!in[G[now][i].to][cost + G[now][i].toll])
     59                 {
     60                     in[G[now][i].to][cost + G[now][i].toll] = true;
     61                     co son;
     62                     son.now = G[now][i].to;
     63                     son.cost = cost + G[tmp.now][i].toll;
     64                     q.push(son);
     65                 }
     66             }
     67         }
     68     }
     69     int minL = INF;
     70     for (int i = 0; i <= k; i++)
     71     {
     72         minL = min(minL, d[n][i]);
     73     }
     74     return minL;
     75 }
     76 
     77 int main()
     78 {
     79     cin >> k >> n >> m;
     80     for (int i = 0; i < m; i++)
     81     {
     82         cin >> s >> t >> l >> T;
     83         node tmp;
     84         tmp.to = t;
     85         tmp.len = l;
     86         tmp.toll = T;
     87         if (s != t)
     88             G[s].push_back(tmp);
     89     }
     90     memset(d, 0x3f, sizeof(d));
     91     for (int i = 0; i <= k; i++)
     92     {
     93         d[1][i] = 0;
     94     }
     95     int minLen = spfa();
     96     if (minLen >= INF)
     97         puts("-1");
     98     else
     99         cout << minLen << endl;
    100     return 0;
    101 }

     最优性剪枝总结:

    1. 从初始状态到当前状态的代价已经不小于目前找到的最优解,则剪枝。

    2. 预测一下从当前状态到解的状态至少要花的代价W,如果W加上到达当前状态时已经花费的代价,必然不小于目前找到的最优解,则剪枝。

    3. 如果到达某个状态A时,发现前面曾经也到达过A,且前面那次到达A所花代价更少,则剪枝。这要求记录到目前为止到达状态A时所能取得的最小代价。

  • 相关阅读:
    singleton 单例模式
    try catch finall 结构里的 return
    ConcurrentHashMap
    ConcurrentHashMap原理分析
    Java 实现两个整数变量的交换
    Java reflect 反射 3 Class.forname
    Java reflect 反射 2
    Java reflect 反射 1
    java class load 类加载
    HashMap源码解析
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6347814.html
Copyright © 2020-2023  润新知