1018. Public Bike Management (30)

1.题目给出一个缺单车的站点,要求求出最小耗费路径,如果最小耗费路径不唯一,需要进行下面的处理。

2.采用dijkstra计算出最小耗费cost,再用最小耗费cost作为约束条件,进行遍历。

3.关键在于后面如何选择最优的路径,选择需要发送最小数量的路径,如果两者发送的数量相同,则选择take数量最小的路径。

4.如0->2->3->4->5, 节点2缺单车,需要send,而节点3单车多出来,只能够补充4或者5的单车,不能反过来补充节点2的单车。

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.

The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.

When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.

pat1018
Figure 1
Figure 1 illustrates an example. The stations are represented by vertices and the roads correspond to the edges. The number on an edge is the time taken to reach one end station from another. The number written inside a vertex S is the current number of bikes stored at S. Given that the maximum capacity of each station is 10. To solve the problem at S3, we have 2 different shortest paths:

1. PBMC -> S1 -> S3. In this case, 4 bikes must be sent from PBMC, because we can collect 1 bike from S1 and then take 5 bikes to S3, so that both stations will be in perfect conditions.

2. PBMC -> S2 -> S3. This path requires the same time as path 1, but only 3 bikes sent from PBMC and hence is the one that will be chosen.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 numbers: Cmax (<= 100), always an even number, is the maximum capacity of each station; N (<= 500), the total number of stations; Sp, the index of the problem station (the stations are numbered from 1 to N, and PBMC is represented by the vertex 0); and M, the number of roads. The second line contains N non-negative numbers Ci (i=1,…N) where each Ci is the current number of bikes at Si respectively. Then M lines follow, each contains 3 numbers: Si, Sj, and Tij which describe the time Tij taken to move betwen stations Si and Sj. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print your results in one line. First output the number of bikes that PBMC must send. Then after one space, output the path in the format: 0->S1->…->Sp. Finally after another space, output the number of bikes that we must take back to PBMC after the condition of Sp is adjusted to perfect.

Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. The judge’s data guarantee that such a path is unique.

Sample Input:

10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1

Sample Output:

3 0->2->3 0

AC代码:
[c language=”++”]
//
// main.cpp
// the beauty of programming
//
// Created by siukwan on 15/08/26.
// Copyright (c) 2015年 siukwan. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <vector>
#include <stack>
#include <algorithm>
#include <memory.h>
#include "limits.h"
using namespace std;

class vertexNode{
public:
vector<int> list;
bool visited, sured;
long long cost;
int cap;
vertexNode() :list(0), visited(false), sured(false), cost(INT_MAX), cap(0){};
};

void dfs(vector<bool> & used,int now,int target,
long long nowCost,long long &minCost,vector<vector<int>>&ans,vector<int>&path,vector<vertexNode>& v,
vector<vector<long long>>&w )
{
if (now == target&&nowCost == minCost)
{
ans.push_back(path);
}
else
{
for (int i = 0; i < v[now].list.size(); i++)
{
int p = v[now].list[i];
if (!used[p] && nowCost + w[now][p] <= minCost)
{
used[p] = true;
path.push_back(p);
dfs(used, p, target, nowCost + w[now][p], minCost, ans, path, v, w);
path.pop_back();
used[p] = false;
}
}
}
};

int main(void)
{
int capMax, n, sp, m;
cin >> capMax >> n >> sp >> m;
n++;//PBMC记为0,接下来的城市为1~n,所以n++
vector<vertexNode> v(n);
for (int i = 1; i < n; i++)
{
cin >> v[i].cap;
}
vector<vector<long long> > w(n, vector<long long>(n, INT_MAX));
for (int i = 0; i < m; i++)
{
int a, b, c;
cin >> a >> b >> c;
if (w[a][b] > c)
{
w[a][b] = c;
w[b][a] = c;
v[a].list.push_back(b);
v[b].list.push_back(a);
}
}

v[0].visited = true;
v[0].cap = 0;
v[0].cost = 0;
while (1)
{
int p = -1;
for (int i = 0; i < n; i++)
{//找出已经探索的最小耗费的点
if (p == -1 && v[i].visited&&!v[i].sured)
p = i;
else if (p != -1 && v[i].visited&&!v[i].sured && v[p].cost > v[i].cost)
p = i;
}
if (p == -1) break;
v[p].sured = true;//确定p点
if (v[sp].sured) break;//目标点的最短路径确认后,不再遍历
for (int i = 0; i < v[p].list.size(); i++)
{
int q = v[p].list[i];
if (!v[q].sured && v[p].cost + w[p][q] < v[q].cost)
{//更新最短路径
v[q].visited = true;
v[q].cost = v[p].cost + w[p][q];
}
}
}

vector<bool> used(n, false);
long long minCost = v[sp].cost;//最小耗费
vector<vector<int>> ans(0, vector<int>(0));
vector<int> path(0);
dfs(used, 0, sp, 0, minCost, ans, path, v, w);
int minSendBike=INT_MAX;
int minCurBike=INT_MAX;
int minIndex=-1;
for (int i = 0; i < ans.size(); i++)
{//遍历每个答案
int sendBike = 0;
int curBike = 0;
int perfectCap = capMax/2;
for (int j = 0; j < ans[i].size(); j++)
{
if(v[ans[i][j]].cap+curBike < perfectCap)
{//如果当前单车总数加上节点的现有单车数都达不到完美容量,则需要send
sendBike+=perfectCap-v[ans[i][j]].cap-curBike;
curBike=0;
}
else
{
curBike=v[ans[i][j]].cap+curBike-perfectCap;
}
}
if(minSendBike>sendBike)
{//如果发送单车数量小于当前最小值,则更新
minSendBike=sendBike;
minIndex=i;
minCurBike=curBike;
}
else if(minSendBike==sendBike && minCurBike>curBike)
{//如果send的数量相同,则判断需要take的最小值,进行更新
minSendBike=sendBike;
minIndex=i;
minCurBike=curBike;
}

}
long long send;
long long take;
send=minSendBike;
take=minCurBike;
cout << send << " ";
if (ans[minIndex].size() > 0)
{
cout << "0";
for (int i = 0; i < ans[minIndex].size(); i++)
{
cout << "->"<< ans[minIndex][i] ;
}
}
cout << " "<< take << endl;

return 0;
}

[/c]

Leave a Reply

Your email address will not be published. Required fields are marked *