• 1018 Public Bike Management


    原题链接: https://www.patest.cn/contests/pat-a-practise/1018)

    选择最短路径比较简单,dijkstra算法即可,但是要考虑send_bikes和back_bikes,注意在去程途中,如果先前的节点中有多余的自行车,可以提供给后面站点,这样从PBMC中带出的自行车就会少一点,但是返程途中不可以再将带回的自行车放置在其他站点中,比如一条路线为6->7->3->6;那么send_bikes =0, back_bikes = 2。

    代码思路是dijkstra算法先找出所有的最短路径,然后回溯,选择满足条件的结果,思路还是比较清晰的。PS:这道题目真心是太烦了

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <string>
    using namespace std;
    
    const int INF = 0x6FFFFFFF;
    int Cmax, N, Sp, M;
    
    int bikes[501]; //每一个节点含有的自行车数量
    int graph[501][501]; //
    
    
    int dist[501];
    vector<int> path[501];
    
    void dijkstra() {
        int source = 0;
        int flag[501];
        int k;
        for (size_t i = 0; i <= N; i++)
        {
            flag[i] = 0;
            dist[i] = graph[0][i];
            path[i].push_back(0);
        }
        flag[source] = 1;
        dist[source] = 0;
    
    
        for (size_t i = 1; i <= N; i++)
        {
            int min = INF; //find the closest point
            for (size_t j = 1; j <= N; j++)
            {
                if (flag[j] == 0 && dist[j] < min) {
                    min = dist[j];
                    k = j;
                }
            }
            flag[k] = 1;
            for (size_t j = 1; j <= N; j++) {
                if (flag[j] == 0) {
                    int tmp = min + graph[k][j];
                    if (tmp < dist[j]) {
                        dist[j] = tmp;
                        path[j].clear();
                        path[j].push_back(k);
                    }
                    else if (tmp == dist[j]) {
                        path[j].push_back(k);
                    }
    
                }
            }
    
        }
    
    }
    
    vector<int> one_path, best_path;
    int min_back_bike = INF, min_send_bike = INF;
    
    void dp(int node) {
    
        if (node == 0) {
            int back = 0;
            int send = 0;
    
            for (int i = one_path.size() - 2; i >= 0; i--)
            {
    
                int t = one_path[i];
                if (bikes[t] > (Cmax / 2))
                    back += bikes[t] - Cmax / 2;
                else if (bikes[t] < (Cmax / 2)) {
                    back += bikes[t] - Cmax / 2;
                    if (back < 0) {
                        send += -back;
                        back = 0;
                    }
                }
            }
    
            if (send < min_send_bike) {
                min_send_bike = send;
                min_back_bike = back;
                best_path = one_path;
            }
            else if (send == min_send_bike && back < min_back_bike) {
                min_back_bike = back;
                best_path = one_path;
            }
    
        }
        else {
            for (size_t i = 0; i < path[node].size(); i++) {
                one_path.push_back(path[node][i]);
                dp(path[node][i]);
                one_path.pop_back();
    
            }
        }
    }
    
    
    int main(void)
    {
        cin >> Cmax >> N >> Sp >> M;
        for (size_t i = 0; i <= N; i++) {
            for (size_t j = 0; j <= N; j++) {
                graph[i][j] = INF;
            }
            graph[i][i] = 0;
        }
    
        for (size_t i = 1; i <= N; i++)
            cin >> bikes[i];
    
        for (size_t i = 0; i < M; i++)    {
            int m, n, t;
            cin >> m >> n >> t ;
            graph[m][n] = t;
            graph[n][m] = t;
        }
    
    
        dijkstra();
        one_path.push_back(Sp);
        dp(Sp);
    
    
        cout << min_send_bike << " " << 0;
        for (int i = best_path.size() - 2; i >= 0; i--)
            cout << "->" << best_path[i];
        cout << " " << min_back_bike << endl;
    
    }
  • 相关阅读:
    博弈论嘻嘻
    cf之kmp匹配稍稍改一改
    点分治开始!
    后缀数组
    cf之 前缀和差分
    AJAX 数据库实例
    常用jar包用途
    cxf客户端所需最少jar包
    Dbutis
    dbutils入门
  • 原文地址:https://www.cnblogs.com/willwu/p/6601444.html
Copyright © 2020-2023  润新知