码迷,mamicode.com
首页 > 其他好文 > 详细

【PAT】A1018 Public Bike Management

时间:2020-02-16 13:22:29      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:names   cout   mic   ips   width   tab   赋值   for   turn   

【思路】

题目生词

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 }

 

【PAT】A1018 Public Bike Management

标签:names   cout   mic   ips   width   tab   赋值   for   turn   

原文地址:https://www.cnblogs.com/yue36/p/12316123.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!