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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值