PAT 甲级 1018 Public Bike Management (30 分)(dijstra+dfs,dfs记录路径,做了两天)
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 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 (≤), always an even number, is the maximum capacity of each station; N (≤), 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 (,) 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. 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
题意:
每个自行车车站的最大容量为一个偶数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记录路径,做了两天)的更多相关文章
- 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)
题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...
- PAT甲级1018. Public Bike Management
PAT甲级1018. Public Bike Management 题意: 杭州市有公共自行车服务,为世界各地的游客提供了极大的便利.人们可以在任何一个车站租一辆自行车,并将其送回城市的任何其他车站. ...
- 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 ...
- 1018 Public Bike Management (30 分)
There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...
- 1018 Public Bike Management (30分) 思路分析 + 满分代码
题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...
- 1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs
前言: 本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/detail ...
- PAT A 1018. Public Bike Management (30)【最短路径】
https://www.patest.cn/contests/pat-a-practise/1018 先用Dijkstra算出最短路,然后二分答案来验证,顺便求出剩余最小,然后再从终点dfs回去求出路 ...
- 1018 Public Bike Management (30分) (迪杰斯特拉+dfs)
思路就是dijkstra找出最短路,dfs比较每一个最短路. dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关, ...
- 1018 Public Bike Management (30)(30 分)
时间限制400 ms 内存限制65536 kB 代码长度限制16000 B There is a public bike service in Hangzhou City which provides ...
随机推荐
- PAT Advanced 1140 Look-and-say Sequence (20 分)
Look-and-say sequence is a sequence of integers as the following: D, D1, D111, D113, D11231, D112213 ...
- php中float浮点型字段查询问题(数据对应不上)
薪资表 查询员工提成时候 比如说表里面是88.8 查询出来则是89 反复调试 未果,最后查看表设计 把金额字段类型设置成float 最后换成double 解决问题!!!!
- Selenium(一)自动化测试简介
1.软件开发流程 产品分析需求--架构师确认系统包含哪些模块--开发编码--开发和测试一起做单元测试--测试开展版本(集成)测试(使用手工测试,测试通过后,才开始设计脚本)--测试开展系统测试--最后 ...
- unittest简单使用的介绍
无论是paython+request接口测试.ui自动化测试等,都常会用到unittest的框架,简单的介绍如下:
- XML 命名规范
XML 元素必须遵循以下命名规则: 名称可以含字母.数字以及其他的字符 名称不能以数字或者标点符号开始 名称不能以字符 "xml"(或者 XML.Xml)开始 名称不能包含空格 可 ...
- BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 (高斯消元)
题面 题目传送门 分析 令爆炸概率为PPP.设 f(i)=∑k=0∞pk(i)\large f(i)=\sum_{k=0}^{\infty}p_k(i)f(i)=∑k=0∞pk(i),pk(i)p ...
- git 在eclipse中忽略上传文件
在我们的工程项目中,有些文件是不需要上传到服务器上的,比如那些 */target/ */bin/*.settings/*.classpath*.gitignore*.project 我们将这些文件添加 ...
- 解决每次执行Java等命令时都要重新source /etc/profile后才能执行,否则找不到命令
linux mint 我们通常将环境变量设置在/etc/profile这个文件中,这个文件是全局的. /etc/profile:在登录时,操作系 统定制用户环境时使用的第一个文件 ,此文件为系统的每个 ...
- QPS 和 TPS
- MySQL 源码编译安装脚本
cat mysql_init.shmysql_init.sh mysql_init.sh.20190401 mysql_init.sh.back20171030 ...