PAT Advanced Level 1003. Emergency (25)(Java and C++)
属于最短路径问题。
解题思路:
1、我先用了SPFA(Shortest Path Faster Agorithm)算法(或者可以用Dijkstra算法),求出最短路径。
使得 int[] dis 数组中保存了各结点的最短路径
2、然后使用了 DFS,注意改变shortestPathCount和rescueTotal处的两个判断条件:
if(st == des){//到达目的地,结束DFS
if( distance==dis[des]){//且是以最小路径到达!!!
shortestPathCount++;
}
//以最小路径到达目的地,并且该路径的rescueTeamSum大于静态变量rescueTotal中存放的历史最大!!!
if(distance==dis[des] && rescueTeamSum >rescueTotal){
rescueTotal=rescueTeamSum;
}
return ;
}
if(dis[st] >dis[des]){//走了更远的路径,结束DFS
return ;
}
Sample Input
5 6 0 2 1 2 1 5 3 0 1 1 0 2 2 0 3 1 1 2 1 2 4 1 3 4 1Sample Output
2 4Sample Input的拓扑图如下:
JAVA代码如下:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Vector;
public class Main_1003_spfa {
static Main_1003_spfa instance =new Main_1003_spfa();
static int[] dis ;
static int[] rescue;
static int[] vis;
static Vector<Edge>[] map;
static final int INF =Integer.MAX_VALUE-10000;
public static void main(String[] arg){
Scanner sc =new Scanner(System.in);
int N =sc.nextInt();
int M =sc.nextInt();
int st =sc.nextInt();
int des =sc.nextInt();
map =new Vector[N];
rescue=new int[N];
dis =new int[N];
vis =new int[N];
for(int i=0;i<N;i++){//初始化
rescue[i]=sc.nextInt();
dis[i] =INF;
map[i]=new Vector<Edge>();
vis[i]=0;
}
for(int i=0;i<M;i++){
int c1 = sc.nextInt();
int c2 = sc.nextInt();
int distance =sc.nextInt();
Edge e1 =instance.new Edge(c2,distance);
map[c1].add(e1);
Edge e2 =instance.new Edge(c1,distance);
map[c2].add(e2);
}
ShortestPathFasterAlgorithm(st);
dfs(st,des,rescue[st],dis[st]);
System.out.println(shortestPathCount+" "+rescueTotal);
}
public static void ShortestPathFasterAlgorithm(int st){
Queue<Integer> q =new LinkedList<Integer>();
q.add(st);
dis[st]=0;
vis[st]=1;
while(!q.isEmpty()){
int cur =q.poll();
vis[cur] =0;
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;
//dis[]
if(dis[cur] + len <dis[to]){
dis[to] = dis[cur] + len;
if(vis[to]==0){
q.add(to);
vis[to]=1;
}
}
}
}
}
static int shortestPathCount=0;
static int rescueTotal =0;
public static void dfs(int st,int des,int rescueTeamSum,int distance){
if(st == des){//到达目的地
if( distance==dis[des]){//且是以最小路径到达
shortestPathCount++;
}
//以最小路径到达目的地,并且该路径的rescueTeamSum大于静态变量rescueTotal中存放的历史最大
if(distance==dis[des] && rescueTeamSum >rescueTotal){
rescueTotal=rescueTeamSum;
}
return ;
}
if(dis[st] >dis[des]){//走了更远的路径
return ;
}
Vector<Edge> adjCities = map[st];
for(int i =0;i<adjCities.size();i++){
int to =adjCities.get(i).to;
int len=adjCities.get(i).len;
if(dis[st]+len <= dis[to]){
dfs(to,des,rescueTeamSum+rescue[to],dis[to]);
}
}
}
class Edge{
int to;
int len;
public Edge (int to ,int len){
this.to =to ;
this.len =len;
}
}
}
C++:
http://www.cnblogs.com/yanhaiming/archive/2012/12/01/2797037.html