zoukankan      html  css  js  c++  java
  • [PAT] A1018 Public Bike Management

    题目大意

    给出需要调整的车站编号,从0处出发,一路上顺便调整途径的车站,使得每个车站的车辆数是Cmax的一半,多的带走少的补齐。选最短路,最短相同选从0处带的车最少的路,若还相同则选择带回0处的车最少的路。
    输出要带的车辆数,路径,带回的车辆数(返回时直接回,不再调整)。

    思路

    题目生词

    figure
    n. 数字
    v. 认为,认定;计算;是……重要部分

    The stations are represented by vertices and the roads correspond to the edges.
    顶点表示车站,边表示道路。

    correspond to 相当于

    capacity
    n. 能力;容量

    方法

    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代码

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<vector>
    using namespace std;
    #define N 502
    #define INF 100000000
    int cmax, stations, goal, roads;
    int bike[N];
    int length[N][N] = { {0} };
    bool vis[N] = {};
    int d[N];
    vector<int>pre[N], path, bestpath;
    int minbring = INF, minback = INF; 
    void DFS(int v)
    {
        if (v == 0){ //到边界--起始节点。
             //计算第二、三标尺的值,即带去、带回的车辆数。
             path.push_back(v);
             int bring = 0, trans = 0;
             for (int i = path.size() - 2; i >= 0; i--) {//倒着来才是路径的正序
                 int  u = path[i];
                 if (bike[u] + trans >= cmax / 2) 
                     trans += bike[u] - cmax / 2;
                 else {
                     bring += cmax / 2 - bike[u] - trans;
                     trans = 0;
                 }
             }
             //更新最优值。
             if (bring < minbring) {
                 bestpath = path;
                 minbring = bring;
                 minback = trans;
             }
             else if (bring == minbring) {
                 if (trans < minback) {
                     bestpath = path;
                     minback = trans;
                 }
             }
             path.pop_back();
             return;
        }
         path.push_back(v);
         for (int i = 0; i < pre[v].size(); i++)        
             DFS(pre[v][i]);
         path.pop_back();
    }
    void Dijkstra(int s)
    {
         int i, j;
         fill(d, d + N, INF);
         d[s] = 0;
         for (i = 0; i <= stations; i++) { //找不在s集中的d最小
             int min = INF, u = -1;
             for (j = 0; j <= stations; j++) {
                 if (min > d[j] && vis[j] == 0) {
                     min = d[j];
                     u = j;
                 }
             }
             if (u == -1)return;
             vis[u] = true;
             //对于通过u能到s的点v,更新路径
             for (j = 0; j <= stations; j++) {
                 if (length[u][j] && vis[j] == 0) {
                     if (d[u] + length[u][j] < d[j]) {
                         d[j] = d[u] + length[u][j];
                         pre[j].clear();
                         pre[j].push_back(u);
                     }
                     else if (d[u] + length[u][j] == d[j]) 
                         pre[j].push_back(u); 
                 }
             }
         }
    }
    int main()
    {
         cin >> cmax >> stations >> goal >> roads;
         int i;
         for (i = 1; i <= stations; i++)
             cin >> bike[i];
         for (i = 0; i < roads; i++) {
             int u, v;
             cin >> u >> v;
             cin >> length[u][v];
             length[v][u] = length[u][v];
         }
         Dijkstra(0);
         DFS(goal);
         cout << minbring << " 0";
         for (i = bestpath.size() - 2; i >= 0; i--)
             cout << "->" << bestpath[i];
         cout << " " << minback;
         return 0;
    }
    
  • 相关阅读:
    iOS 字符串的UTF8 编码 以及归档反归档
    iOS 关于关键字高亮
    iOS 适配 ,关于prefix Header 文件的配置
    关于collectionView 的头视图
    关于页面的下拉刷新,和上拉加载 --- > collectionView ,tableView
    Nums数独计算器的感谢版,有3种解题方式,过去注册的也是可以用
    Nums数独计算器,良心软件,给不给钱都是可以的
    人生不过是给自己找一些痕迹,证明自己存在过
    做些有益的事情,人生要懂得自重
    振作才是自己可以走的路,人生不要放弃自己的争取
  • 原文地址:https://www.cnblogs.com/yue36/p/13374841.html
Copyright © 2011-2022 走看看