您的位置:首页 > 其它

1018. Public Bike Management (30)

2017-01-04 20:28 357 查看
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.



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:

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.

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

算法分析:这道题主要思路还是考虑Dijkstra算法,但是与之前不同的是要记录所有最短路径,这是这道题的一个难点。要知道所有的最短路径组在一起还是一个图,所以用深度优先搜索来遍历每一条最短路径,来选出最好的路径,这是这道题另一个难点。具体解析见代码注释。

#include <stdio.h>
#include <stdlib.h>
#define INF 65535

int g[501][501]; //图的邻接矩阵
int visited[501] = {0}, numBike[501] = {0}, dist[501]; //老套路+每个顶点单车的数量
int stack[501], top = 0; //堆栈,用来遍历所有路径,后面有详细解释
int bestPath[501], x = 0; //数组,用来存储最好路径
int cmax, n, sp, m;
int send = INF, back = INF; //0号顶点发送和接受的单车数目

struct path
{
int vertex[501];
int size;
}path[501]; //记录所有的顶点最短路径的前驱顶点,就是当前顶点前面一层有哪些顶点,类似于传统的path[501]

void Dijkstra() //记录所有的最短路径
{
int i, j;
for(i = 0; i <= n; i++) //初始化dist[]
{
dist[i] = g[0][i];
path[i].size = 0;
}
for(j = 1; j <= n; j++) //初始化path,使每个与0号顶点相邻的顶点都能找到0号顶点
{
if(dist[j] < INF)
path[j].vertex[path[j].size++] = 0;
}
visited[0] = 1;
for(i = 0; i <= n; i++) //开始Dijkstra算法
{
int min = INF, v = 0;
for(j = 0; j <= n; j++) //找到距离原点最近的点
{
if(!visited[j] && dist[j] < min)
{
min = dist[j];
v = j;
}
}
visited[v] = 1;
for(j = 0; j <= n; j++) //记录所有路径
{
if(!visited[j] && g[v][j] < INF)
{
if(dist[v] + g[v][j] < dist[j])
{
dist[j] = dist[v] + g[v][j];
path[j].vertex[0] = v;
path[j].size = 1;
}
else if(dist[v] + g[v][j] == dist[j])
path[j].vertex[path[j].size++] = v;
}
}
}
}

void dfs(int v) //遍历每一条最短路径
{
int i;
stack[top++] = v; //压栈
if(v == 0) //表示搜索出一整条最短路径,注意此时堆栈中正好是一条完整的最短路径
{
int s = 0, count = 0;
for(i = top - 2; i >= 0; i--) //从1号顶点开始
{
count += numBike[stack[i]] - cmax / 2; //count记录需要拿走或带来多少单车
if(count < 0) //count<0表示需要带来单车
{
s -= count; //s表示需要带来的单车数量
count = 0;
}
}
if(s < send || (s == send && count < back)) //如果需要带来的单车数量小于最好的结果
{ //或者需要带来的单车数量相等,就看需要带回去的单车数
send = s; //记录当前最好的结果
back = count;
x = 0;
for(i = top - 1; i >= 0; i--) //记录当前最好的路径
bestPath[x++] = stack[i];
}
return;
}
for(i = 0; i < path[v].size; i++)
{
dfs(path[v].vertex[i]);
top--; //出栈
}
}

int main()
{
int i, j, v, w, weight;
scanf("%d %d %d %d", &cmax, &n, &sp, &m);
for(i = 1; i <= n; i++)
scanf("%d", &numBike[i]);
for(i = 0; i <= n; i++)
{
for(j = 0; j <= n; j++)
{
g[i][j] = INF;
path[i].vertex[j] = -1;
}
}
for(i = 0; i < m; i++)
{
scanf("%d %d %d", &v, &w, &weight);
g[v][w] = weight;
g[w][v] = weight;
}
Dijkstra();
dfs(sp);
printf("%d ", send);
for(i = 0; i < x - 1; i++)
printf("%d->", bestPath[i]);
printf("%d %d", sp, back);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT甲级