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代码如下(有一个测试点始终通不过,希望有大神能够指点,解决的话,送你一个女朋友):
C++代码:
参考博客
使用DFS的代码:
http://blog.csdn.net/huntinggo/article/details/18941253
使用Dijkstra + DFS的代码:
http://www.cnblogs.com/luojiahu/p/3892608.html
最短路径问题。题意有三: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
相关文章推荐
- PAT Advanced Level 1030. Travel Plan (30)(Java and C++)
- Pat Advanced Level 1025(Java and C++)
- PAT Advanced Level 1035 (Java and C++)
- PAT Advanced Level 1043. Is It a Binary Search Tree (25)(Java and C++)
- PAT Advanced Level 1086. Tree Traversals Again (25)(Java and C++)
- PAT (Advanced Level) Practise 1119 Pre- and Post-order Traversals (30)
- 【PAT】【Advanced Level】1119. Pre- and Post-order Traversals (30)
- PAT Advanced Level 1011(Java and C++)
- PAT (Advanced Level) Practise 1119 Pre- and Post-order Traversals (30)
- PAT Advanced Level 1003. Emergency (25)(Java and C++)
- PAT Advanced Level 1085. Perfect Sequence (25)(Java and C++)
- 【PAT Advanced Level】1022. Digital Library (30)
- 【PAT Advanced Level】1068. Find More Coins (30)
- 1022. Digital Library (30) @ PAT (Advanced Level) Practise
- Pat(Advanced Level)Practice--1062(Talent and Virtue)
- PAT Advanced Level 1036(Java)
- Pat(Advanced Level)Practice--1056(Mice and Rice)
- Pat(Advanced Level)Practice--1006(Sign In and Sign Out)
- PAT Advanced Level 1080. Graduate Admission (30)
- PAT Advanced Level 1076. Forwards on Weibo (30)