1018 Public Bike Management (30 分)
 

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.

The above figure 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 S​3​​, we have 2 different shortest paths:

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

  2. PBMC -> S​2​​ -> S​3​​. 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: C​max​​ (≤), always an even number, is the maximum capacity of each station; N (≤), the total number of stations; S​p​​, 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 C​i​​ (,) where each C​i​​ is the current number of bikes at S​i​​ respectively. Then M lines follow, each contains 3 numbers: S​i​​, S​j​​, and T​ij​​ which describe the time T​ij​​ taken to move betwen stations S​i​​ and S​j​​. 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. Finally after another space, output the number of bikes that we must take back to PBMC after the condition of S​p​​ 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

题意:

每个自行车车站的最大容量为一个偶数cmax,如果一个车站里面自行车的数量恰好为cmax / 2,那么称处于完美状态。如果一个车展容量是满的或者空的,控制中心(处于结点0处)就会携带或者从路上手机一定数量的自行车前往该车站,一路上会让所有的车展沿途都达到完美。现在给出cmax,车站的数量n,问题车站sp,m条边,还有距离,求最短路径。如果最短路径有多个,求能带的最少的自行车数目的那条。如果还是有很多条不同的路,那么就找一个从车站带回的自行车数目最少的。带回的时候是不调整的

思路:

首先用dijkstra算法求出PBMC(0点)到目标点的最短距离。然后深搜穷举,每次深搜找到一条最短路径后依次记录路径上的各点,然后扫描,如果有的station少于最大容量的一半,带出的车数就加到take中;如果多了,带回去的车数加到back中。注意,每一站多的车辆只能放到后面一站去,而不能补充前面车站中少的数目。
在dfs中借助栈记录下最好的路径

#include<iostream>
#include<stack>
using namespace std; int maze[][];//迷宫
int vis[][];//记录迷宫中的某个位置是否访问过
int n,m; int dir[][] = {{,},{,-},{,},{-,}};//四个方向 struct point//位置
{
int x,y;
} p; stack<point> path,temp;//记录路径,temp是一个临时变量,和path一起处理路径 int count;//路径条数 void dfs(int x,int y)//x,y:当前位置
{
if(x==n- && y==m-)//成功---下面处理路径问题
{
cout << "******************路径"<< ++count << "******************" << endl;
while(!path.empty())//将path里面的点取出来,放在temp里面
{//path从栈顶-栈底的方向,路径是从终点-起点的顺序
point p1 = path.top();
path.pop();
temp.push(p1);
}
while(!temp.empty())
{//输出temp里面的路径,这样刚好是从起点到终点的顺序
point p1 = temp.top();
temp.pop();
path.push(p1);//将路径放回path里面,因为后面还要回溯!!!
cout << "(" << p1.x << "," << p1.y << ")" << endl;
}
return;
} if(x< || x>=n || y< || y>=m)//越界
return; //如果到了这一步,说明还没有成功,没有出界
for(int i=;i<;i++)//从4个方向探测
{
int nx = x + dir[i][];
int ny = y + dir[i][];//nx,ny:选择一个方向,前进一步之后,新的坐标
if(<=nx && nx<n && <=ny && ny<m && maze[nx][ny]== && vis[nx][ny]==)
{//条件:nx,ny没有出界,maze[nx][ny]=0这个点不是障碍可以走,vis[nx][ny]=0说明(nx,ny)没有访问过,可以访问 vis[nx][ny]=;//设为访问过
p.x = nx;
p.y = ny;
path.push(p);//让当前点进栈 dfs(nx,ny);//进一步探测 vis[nx][ny]=;//回溯
path.pop();//由于是回溯,所以当前点属于退回去的点,需要出栈
}
}
} int main()
{
count = ;
freopen("in.txt","r",stdin);//读取.cpp文件同目录下的名为in.txt的文件 p.x = ;
p.y = ;
path.push(p);//起点先入栈 cin >> n >> m;
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
vis[i][j] = ;
cin >> maze[i][j];
}
}
dfs(,); return ;
}

这个题目有两个比较坑的点:

1.仔细阅读题目,会发现其实有三个优先级判断点:题目正文中要求第一优先级为最短路径,第二优先级为派出自行车最少,而在结果输出中有第三优先级,即收回自行车最少。遗漏后两个优先级会导致有的点通不过;
2.在统计派出数和收回数时,要注意一个站点中多出来的自行车只能向后面的站点补充,而不能向前面的站点补充,这也是很容易忽视的问题。

我的样例:


 ->-> 

 ->->-> 

 ->->-> 

 ->->->-> 

 ->-> 

 ->->->-> 

AC代码:

 #include<bits/stdc++.h>
using namespace std;
int INF = ;
int C,SP,N,M;
int h[];//拥有多少自行车
int e[][];
int d[];
int v[];
int min_go=INF;//带去的越少越好
int min_back=INF;//带回来的越少越好
vector<int>p[];//记录所有最短路径中各个点的前一个有哪些
stack<int>route;
stack<int>final_route;
void clear(stack<int> &s){//清空栈
stack<int> empty;
swap(empty,s);
}
void dijstra()
{
d[]=;
memset(v,,sizeof(v));
for(int i=;i<=N;i++){
d[i]=e[][i];
if(d[i]!=INF)
{
p[i].push_back();
}
}
for(int i=;i<=N-;i++){
int k=-;
int min=INF;
for(int j=;j<=N;j++){
if(v[j]== && min>d[j]){
k=j;
min=d[j];
}
}
if(k==-){
break;
}
v[k]=;
for(int j=;j<=N;j++){
if(v[j]==){
continue;
}
if(d[j]>d[k]+e[k][j])
{
p[j].clear();
p[j].push_back(k);
d[j]=d[k]+e[k][j];
}
else if(d[j]==d[k]+e[k][j]){
p[j].push_back(k);
}
}
}
}
void dfs(int s,int go,int back){
for(int i=;i<p[s].size();i++){
int x=p[s].at(i);
if(x==){
if(min_go>go){//根据优先级更新!
min_go=go;
min_back=back;
final_route=route;//更新最终路线
final_route.push(x);
}else if(min_go==go && min_back>back){
min_go=go;
min_back=back;
final_route=route;//更新最终路线
final_route.push(x);
}
}else{
int g=go+C-h[x];
int b=back;//后面多的不能补到前面!
if(g<){//需要送去的为负数了
b+=(-*g);//反而还要带点回来
g=;//那就不送了
}
route.push(x);
dfs(x,g,b);
route.pop();
}
}
}
int main(){
cin>>C>>N>>SP>>M;
C/=;
for(int i=;i<=N;i++){
cin>>h[i];
p[i].clear();
}
for(int i=;i<=N;i++)
{
for(int j=;j<=N;j++)
{
if (i==j) e[i][j]=;
else e[i][j]=INF;
}
}
for(int i=;i<=M;i++){
int u,v,t;
cin>>u>>v>>t;
e[u][v]=e[v][u]=t;
}
dijstra(); int go=C-h[SP];
int back=;
if(go<){
back=-*go;
go=;
}
clear(route);
clear(final_route);
route.push(SP); dfs(SP,go,back);
//输出
cout<<min_go<<" ";
while(!final_route.empty()){
cout<<final_route.top();
final_route.pop();
if(!final_route.empty()){
cout<<"->";
}
}
cout<<" "<<min_back<<endl; return ;
}

PAT 甲级 1018 Public Bike Management (30 分)(dijstra+dfs,dfs记录路径,做了两天)的更多相关文章

  1. 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)

    题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...

  2. PAT甲级1018. Public Bike Management

    PAT甲级1018. Public Bike Management 题意: 杭州市有公共自行车服务,为世界各地的游客提供了极大的便利.人们可以在任何一个车站租一辆自行车,并将其送回城市的任何其他车站. ...

  3. PAT Advanced 1018 Public Bike Management (30) [Dijkstra算法 + DFS]

    题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...

  4. 1018 Public Bike Management (30 分)

    There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...

  5. 1018 Public Bike Management (30分) 思路分析 + 满分代码

    题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...

  6. 1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs

    前言: 本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/detail ...

  7. PAT A 1018. Public Bike Management (30)【最短路径】

    https://www.patest.cn/contests/pat-a-practise/1018 先用Dijkstra算出最短路,然后二分答案来验证,顺便求出剩余最小,然后再从终点dfs回去求出路 ...

  8. 1018 Public Bike Management (30分) (迪杰斯特拉+dfs)

    思路就是dijkstra找出最短路,dfs比较每一个最短路. dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关, ...

  9. 1018 Public Bike Management (30)(30 分)

    时间限制400 ms 内存限制65536 kB 代码长度限制16000 B There is a public bike service in Hangzhou City which provides ...

随机推荐

  1. 如何判断PHP空间是否支持curl、gzip等功能

    在网站根目录新建v.php,输入以下代码: <?php $f=@trim($_GET['f']); if(function_exists($f)) echo '支持'.$f; else echo ...

  2. Pytest【定制fixture】

    在pytest中的fixture是在测试函数运行前后,由pytest执行的外壳函数,fixture中的代码可以定制,满足多变的测试需求:包括定义传入测试中的数据集.配置测试前系统的初始化状态.为批量测 ...

  3. PWA

    附一个示例e6书写 todolist的示例,切换list的状态: //todolist示例 const toggleTodo = (id)=>{ setTodos(todos => tod ...

  4. 设置easyUI-dialog窗口居中显示

    默认情况下应该是在屏幕居中显示的.但是有的时候没有居中只要重新纠正下就可以了 $('#add_dialog').dialog('open'); //打开添加对话框 $('#add_dialog').w ...

  5. 关于c语言中结构体的初始化

    1.先定义结构体类型后再定义结构体变量: 格式为:struct 结构体名 变量名列表: struct book s1,s2,*ss://注意这种之前要先定义结构体类型后再定义变量: 2.在定义结构体类 ...

  6. PHP mysqli_connect() 函数

    打开一个到 MySQL 服务器的新的连接: mysqli_connect(host,username,password,dbname,port,socket); <?php $con=mysql ...

  7. STS工具:mybayis连接oracle数据库

    1.pom.xml文件中的依赖 刚添加依赖的时候会报错,原因是jar包下不下来. 2.我的jdk是1.6,所以需要升级jdk版本到1.8 执行mvn -v命令,可以看到maven的版本号 DOS窗口执 ...

  8. 【FTP】详解

     FTP协议及工作原理 1. FTP协议  什么是FTP呢?FTP 是 TCP/IP 协议组中的协议之一,是英文File Transfer Protocol的缩写. 该协议是Internet文件传送的 ...

  9. crm-权限管理

    1 用户登录 设置session 将权限存放在session中 2 设置中间件,进行拦截 0 添加白名单,判断是否在白名单上 1 判断是否登录 2 权限过滤

  10. qtableview 表格风格设置

    1.窗体无边框? tableView->setFrameShape(QFrame::NoFrame); 2.表格内容无边框? tableView->setShowGrid(false); ...