PATA1018 Public Bike Management

Posted yue36

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PATA1018 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];
 13 vector<int>path;
 14 int minbring = INF, minback = INF;
 15 vector<int>bestpath;
 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--)
 25         {
 26             int  u = path[i];
 27             if (bike[u] + trans >= cmax / 2)
 28             {
 29                 trans += bike[u] - cmax / 2;
 30             }
 31             else
 32             {
 33                 bring += cmax / 2 - bike[u] - trans;
 34                 trans = 0;
 35             }
 36         }
 37         //更新最优值。
 38         if (bring < minbring)
 39         {
 40             bestpath = path;
 41             minbring = bring;
 42             minback = trans;
 43         }
 44         else if (bring == minbring)
 45         {
 46             if (trans < minback)
 47             {
 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++)
 58     {
 59         DFS(pre[v][i]);
 60     }
 61     path.erase(path.end() - 1);//可以写成path.pop_back();
 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++)
 69     {
 70         //找不在s集中的d最小
 71         int min = INF, u = -1;
 72         for (j = 0; j <= stations; j++)
 73         {
 74             if (min > d[j] && vis[j] == 0)
 75             {
 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++)
 84         {
 85             if (length[u][j] && vis[j] == 0)
 86             {
 87                 if (d[u] + length[u][j] < d[j])    
 88                 {
 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])
 94                 {
 95                     pre[j].push_back(u);
 96                 }
 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++)
110     {
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--)
120     {
121         cout << "->" << bestpath[i];
122     }
123     cout << " " << minback;
124     return 0;
125 }

 

以上是关于PATA1018 Public Bike Management的主要内容,如果未能解决你的问题,请参考以下文章

1018 Public Bike Management (30)

1018 Public Bike Management

1018. Public Bike Management (30)

1018 Public Bike Management (30 分)

1018 Public Bike Management (30分)

PAT A1018.Public Bike Management