1018 Public Bike Management(DFS+dijkstra,最短路径加附加条件判断模板)
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.
这个问题可以抽象为pat的一类模板:多条最短路径同时存在,给出其他条件,在多条最短路径中找到性能最优的一条。
通过dijkstra找到多条最短路径,用二维vector存储,之后再通过DFS重走各条最短路径,在重走的过程中记录路径上的总资源,跟全局的最优解比较,完成替换,得到路径。
#include<iostream>
#include<vector>
using namespace std;
const int Max = 1000000;
int G[501][501],dist[501],w[501];
int minSend = Max, minBack = Max;
bool visited[501];
int C, M,S, K;
vector<int> pre[501],temppath,path;
void DFS(int v) {
temppath.push_back(v);
if (v == 0) {
int send = 0, back = 0;
for (int i = temppath.size()-1; i>=0 ; i--) {
int id = temppath[i];
if (w[id] > 0)
back += w[id];
else
if (0 - w[id] < back) {
back += w[id];
}
else {
send -= (back + w[id]);
back = 0;
}
}
if (send < minSend) {
minSend = send;
minBack = back;
path = temppath;
}else
if (send == minSend && back < minBack) {
minBack = back;
path = temppath;
}
temppath.pop_back();
return;
}
for (int i = 0; i < pre[v].size(); i++)
DFS(pre[v][i]);
temppath.pop_back();
}
int main()
{
cin >> C >> M >> S >> K;
fill(G[0], G[0] + 501 * 501, Max);
fill(dist, dist + 501, Max);
for (int i = 1; i <= M; i++)
{
scanf("%d", &w[i]);
w[i] -= C / 2;
}
for (int i = 0; i < K; i++) {
int a, b, l;
scanf("%d %d %d", &a, &b, &l);
G[a][b] = G[b][a] = l;
}
dist[0] = 0;
while (true) {
int v = -1, min = Max;
for (int i = 0; i <= M; i++) {
if (!visited[i] && dist[i] < min) {
min = dist[i];
v = i;
}
}
if (v == -1)break;
visited[v] = true;
for (int i = 0; i <= M; i++) {
if (!visited[i] && G[v][i] != Max) {
if (dist[i] > dist[v] + G[v][i]) {
dist[i] = dist[v] + G[v][i];
pre[i].clear();
pre[i].push_back(v);
}else
if (dist[i] == dist[v] + G[v][i]) {
pre[i].push_back(v);
}
}
}
}
DFS(S);
printf("%d 0", minSend);
for (int i = path.size() - 2; i >= 0; i--)
printf("->%d", path[i]);
printf(" %d", minBack);
return 0;
}