• [PAT] A1018 Public Bike Management


    【思路】

    题目生词

    figure

    n. 数字

    v. 认为,认定;计算;是……重要部分

    The stations are represented by vertices and the roads correspond to the edges.

    顶点表示车站,边表示道路。

    correspond to 相当于

    capacity

    n. 能力;容量

    题目大意:给出需要调整的车站编号,从0处出发,一路上顺便调整途径的车站,使得每个车站的车辆数是Cmax的一半,多的带走少的补齐。选最短路,最短相同选从0处带的车最少的路,若还相同则选择带回0处的车最少的路。

    输出要带的车辆数,路径,带回的车辆数(返回时直接回,不再调整)。

    方法:Dijkstra + DFS。先用Dijkstra算法算出最短路径,只考虑时间最短,建立vector保存路径的前驱节点。然后用DFS遍历每一条路径,获得一条路径后(即遍历到了起始节点0)计算带去带回的车辆,确定最佳方案。

    计算带去、带回车辆数的方法:对于每个站点,考虑前一个站点传递下来的车辆数trans和自己的车辆数bike[i]相加的结果与cmax/2的差,分两种情况——一,差值为负,即车不够,要从0处带车,所以bring的值增加其差值的绝对值,而传递给下去的车辆数trans置为0;二,差值非负,表示车够了,多出的车赋值给trans传递到下一个站点,bring的值保持。一开始bring和trans的值为0,从出发节点的下一个节点(即0号节点的下一个节点)开始遍历计算。最终bring为要从0处携带的车辆数,trans即带回的车辆数。注意,有关从0处带多少车,只与当前走过的车站有关,即不管后面站点车再多,前面的车不够了,就要从0处带(因为走路不会回头,携带的车辆数是随着路径的推进而变化的)。而DFS是从终点向前推到起点结束,则必须要求完整条路径才能算的出来。最后倒着输出变长数组的值,即为路径。

    【tips】要熟练运用Dijkstra+DFS求最佳路径的算法!

    【AC代码】

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include<iostream>
      3 #include<vector>
      4 using namespace std;
      5 #define N 502
      6 #define INF 100000000
      7 int cmax, stations, goal, roads;
      8 int bike[N];
      9 int length[N][N] = { {0} };
     10 bool vis[N] = {};
     11 int d[N];
     12 vector<int>pre[N], path, bestpath;
     14 int minbring = INF, minback = INF; 16 void DFS(int v)
     17 {
     18     if (v == 0) //到边界--起始节点。
     19     {    
     20         //计算第二、三标尺的值,即带去、带回的车辆数。
     21         path.push_back(v);
     22         int bring = 0;
     23         int trans = 0;
     24         for (int i = path.size() - 2; i >= 0; i--){//倒着来才是路径的正序
     26             int  u = path[i];
     27             if (bike[u] + trans >= cmax / 2) 
    29
    trans += bike[u] - cmax / 2;
    31 else{ 33 bring += cmax / 2 - bike[u] - trans; 34 trans = 0; 35 } 36 } 37 //更新最优值。 38 if (bring < minbring){ 40 bestpath = path; 41 minbring = bring; 42 minback = trans; 43 } 44 else if (bring == minbring){ 46 if (trans < minback){ 48 bestpath = path; 49 minback = trans; 50 } 51 } 52 path.pop_back(); 53 return; 54 } 55 int i; 56 path.push_back(v); 57 for (i = 0; i < pre[v].size(); i++)
    59
    DFS(pre[v][i]);
         path.pop_back(v);
    62 } 63 void Dijkstra(int s) 64 { 65 int i, j; 66 fill(d, d + N, INF); 67 d[s] = 0; 68 for (i = 0; i <= stations; i++){ 70 //找不在s集中的d最小 71 int min = INF, u = -1; 72 for (j = 0; j <= stations; j++){ 74 if (min > d[j] && vis[j] == 0){ 76 min = d[j]; 77 u = j; 78 } 79 } 80 if (u == -1)return; 81 vis[u] = true; 82 //对于通过u能到s的点v,更新路径 83 for (j = 0; j <= stations; j++){ 85 if (length[u][j] && vis[j] == 0){ 87 if (d[u] + length[u][j] < d[j]){ 89 d[j] = d[u] + length[u][j]; 90 pre[j].clear(); 91 pre[j].push_back(u); 92 } 93 else if (d[u] + length[u][j] == d[j])
    95 pre[j].push_back(u);

    97 } 98 } 99 100 } 101 } 102 103 int main() 104 { 105 cin >> cmax >> stations >> goal >> roads; 106 int i; 107 for (i = 1; i <= stations; i++) 108 cin >> bike[i]; 109 for (i = 0; i < roads; i++) { 111 int u, v; 112 cin >> u >> v; 113 cin >> length[u][v]; 114 length[v][u] = length[u][v]; 115 } 116 Dijkstra(0); 117 DFS(goal); 118 cout << minbring << " 0"; 119 for (i = bestpath.size() - 2; i >= 0; i--)

    121 cout << "->" << bestpath[i];

    123 cout << " " << minback; 124 return 0; 125 }
  • 相关阅读:
    Vue $emit()不触发方法的原因
    java 定时任务之一 @Scheduled注解(第一种方法)
    Dubbo的使用及原理浅析.
    Android App 安全的HTTPS 通信
    详解intellij idea搭建SSM框架(spring+maven+mybatis+mysql+junit)
    IDEA 2018集成MyBatis Generator 插件 详解
    自建证书配置HTTPS服务器
    Jsoup(一)Jsoup详解(官方)
    Android使用最小宽度限定符时最小宽度的计算
    可显示行号的log工具
  • 原文地址:https://www.cnblogs.com/yue36/p/12316123.html
Copyright © 2020-2023  润新知