您的位置:首页 > 编程语言 > C语言/C++

PAT Advanced Level 1018. Public Bike Management (30)(Java and C++)

2014-09-18 20:58 489 查看
PAT Advanced Level 1018. Public Bike Management (30)

最短路径问题。题意有三:1.时间最短 2.送出车辆最少 3.回收车辆最少 ps:(注意我的lessThan函数)

我的思路:是 SPFA(求出最短路径) + DFS(获取到Destination的所有最短路径并存入pathVector)+遍历path(求出各path min_send 和 min_back)

最终获取send最下的path输出(当有多个send相同的path,取back最小的)。

======================================================================================

大神的陷阱总结:

大神A:

这个题目自我感觉说的不太明确, 知道算法可能还要注意一下两点才能AC:

(1) 从PBMC到问题站点, 只能在这个顺序上进行每个站点车辆数量的调整, 在从问题站点返回PBMC的时候不能调整路径上的站点, 所以这个就导致有可能从PBMC送出去车辆也有可能带回来车辆(直觉上好像不太合理, 既然要带回来, 那么从出去的时候干嘛不少送一点呢?但是没办法, 这个题目似乎就是这么要求的)

(2) 从哪些最短路径总选择调整的车辆的数量最小的那条时, 题目总的描述非常模糊以及容易误导, 题目中是这么说的:“If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.”, 我一开始理解成了只要比较送出去的车辆的数量就行了, 其实测试数据才不是这么测试的呢, 其实应该按照“首先选择send最少的,send相同时选择take
back最少的。
“这条标准从所有的最短路径中选择 (第七个case应该就是卡在这里).

大神B:

陷阱:调整路径上站点的车辆数目时,不能把后面站点多出来的车辆返补回前面车辆数不够的站点。乍看之下这是符合逻辑的,因为在前面的站点的时候不能知道后面的站点是什么情况,所以按理应该逐个调整合理,后面的站点影响不到前面的调整。但是细想之后发现这其实是很死板的做法,现实当中设计这样一个管理系统肯定能够实时收集每个站点的自行车数,所以在出发前应该就能得出这条路径上总的自行车数目,继而就能得到最优的送出数。但四十是介样子素通不过滴。

======================================================================================

Java代码如下(有一个测试点始终通不过,希望有大神能够指点,解决的话,送你一个女朋友):
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Vector;

public class Main {
static Main instance =new Main();
static int[] sBikes;
static int[] dis;
static final int Inf =Integer.MAX_VALUE-10000;
static Vector<Edge>[] map;
static boolean[]   vis;
static int Cmax;
static int N;
static int Sp;
static int M;
public static void main(String[] args){
Scanner sc =new Scanner(System.in);
Cmax =sc.nextInt();
N    =sc.nextInt();
Sp   =sc.nextInt();
M    =sc.nextInt();

sBikes =new int[N+1];
dis      =new int[N+1];
map      =new Vector[N+1];
vis      =new boolean[N+1];
for(int i=0;i<=N;i++){
if(i==0){
sBikes[i]=Inf;
}
else{
sBikes[i]=sc.nextInt();
}
map[i] =new Vector<Edge>();
dis[i] =Inf;
vis[i] =false;
}

for(int i=0;i<M;i++){
int s1  = sc.nextInt();
int s2  = sc.nextInt();
int len = sc.nextInt();
Edge e1 =instance.new Edge();
e1.to=s2;
e1.len=len;
map[s1].add(e1);
Edge e2 =instance.new Edge();
e2.to =s1;
e2.len=len;
map[s2].add(e2);
}
spfa(0);

DFS(0,Sp,0);
Path path;
int extra;
for(int i=0;i<pathVector.size();i++){
path=pathVector.get(i);
Vector<Integer> stations =path.stations;
extra =0;
for(int j=0;j<stations.size();j++){
if(sBikes[stations.get(j)] <Cmax/2){
if(extra>0){
if(extra > Cmax/2-sBikes[stations.get(j)]){
extra -= Cmax/2-sBikes[stations.get(j)];
}
else{
path.send += Cmax/2-sBikes[stations.get(j)]-extra;
extra = 0;
}
}
else{
path.send += Cmax/2-sBikes[stations.get(j)];
}
}
else if(sBikes[stations.get(j)] >Cmax/2){
extra += sBikes[stations.get(j)] -Cmax/2;
}
}
path.back=extra;
}
path =pathVector.get(0);
for(int i=0;i<pathVector.size();i++){
if(lessThan(pathVector.get(i),path)){
path = pathVector.get(i);
}
}
System.out.print(path.send+" 0");
for(int i=0;i<path.stations.size();i++){
System.out.print("->"+path.stations.get(i));
}
System.out.print(" "+path.back);
}

public static boolean lessThan(Path p1,Path p2){
if(p1.send < p2.send)
return true;
if(p1.send == p2.send && p1.back < p2.back)
return true;
else
return false;
}

public static void spfa(int start){
dis[start]=0;
Queue<Integer> q =new LinkedList<Integer>();
q.add(start);
vis[start]=true;
while(!q.isEmpty()){
int cur =q.poll();
vis[cur]=false;
Vector<Edge> adjEdges =map[cur];
for(int i=0;i<adjEdges.size();i++){
int to =adjEdges.get(i).to;
int len=adjEdges.get(i).len;
if(dis[cur]+len <dis[to]){
dis[to] =dis[cur]+len;
if(!vis[to]){
q.add(to);
vis[to]=true;
}
}
}
}
}

static Vector<Integer> onePath = new Vector<Integer>();
static Vector<Path>   pathVector = new Vector<Path> ();

public static void DFS(int st,int des,int distance){

if(st==des){
if(distance==dis[des]){
Vector<Integer> one_Path = new Vector<Integer>();
for(int i=0;i<onePath.size();i++){
one_Path.add(onePath.get(i));
}
Path path =instance.new Path();
path.stations=one_Path;
pathVector.add(path);
}
onePath.clear();
return ;
}
if(distance>dis[des]){
onePath.clear();
return;
}
Vector<Edge> adjEdges =map[st];
for(int i=0; i<adjEdges.size();i++){
int to =adjEdges.get(i).to;
int len=adjEdges.get(i).len;
if(dis[st]+len <= dis[to]){
onePath.add(to);
DFS(to,des,dis[st]+len);
}
}
onePath.clear();
}
class Path{
Vector<Integer> stations;
int send=0;
int back=0;
}

class Edge{
int to;
int len;
}
}


C++代码:

参考博客
使用DFS的代码:
http://blog.csdn.net/huntinggo/article/details/18941253
使用Dijkstra + DFS的代码:
http://www.cnblogs.com/luojiahu/p/3892608.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: