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;

}
posted @ 2017-03-22 18:39  WillWu  阅读(179)  评论(0编辑  收藏  举报