最短路径类问题,题目链接如下:
PAT(A)1030
本题是最短路径问题的变形,即每一条路径的权值有两个,当第一个权值相等时认为第二个权值小的路径更短,再输出其最短路径即可,因此,只需稍稍改良Dijkstra算法即可,具体AC代码如下:
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
public class Main {
static int start,end;
final static int MAX=65536;
static int n,m;
static Path[][] p;
static Path[] cost;
static int [] visited;
static int[]pre;
static int start2;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
start=sc.nextInt();
end=sc.nextInt();
start2=start;
p=new Path[n][n];
cost=new Path[n];
for(int i=0;i<n;i++)
cost[i]=new Path(MAX,MAX);
cost[start]=new Path(0, 0);
pre=new int[n];
visited=new int[n];
for(int i=0;i<n;i++){
pre[i]=-1;
visited[i]=0;
}
pre[start]=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
p[i][j]=new Path(MAX, MAX);
p[j][i]=new Path(MAX, MAX);
}
for(int i=0;i<m;i++){
int a=sc.nextInt();
int b=sc.nextInt();
Path path=new Path(sc.nextInt(), sc.nextInt());
p[a][b]=p[b][a]=path;
}
while(start!=-1){
for(int i=0;i<n;i++){
if(visited[i]==0&&start!=i && p[start][i].value1+cost[start].value1<=cost[i].value1){
if(p[start][i].value1+cost[start].value1<cost[i].value1){
cost[i].value1=p[start][i].value1+cost[start].value1;
cost[i].value2=p[start][i].value2+cost[start].value2;
pre[i]=start;
}
else{
if(p[start][i].value2+cost[start].value2<cost[i].value2){
cost[i].value1=p[start][i].value1+cost[start].value1;
cost[i].value2=p[start][i].value2+cost[start].value2;
pre[i]=start;
}
}
}
}
visited[start]=1;
start=f();
}
Stack<Integer> stack=new Stack<Integer>();
stack.add(end);
while(pre[end]!=start2){
end=pre[end];
stack.add(end);
}
stack.add(start2);
int spend1=0,spend2=0;
int a,b=-1;
a=stack.pop();
b=stack.pop();
spend1+=p[a][b].value1;
spend2+=p[a][b].value2;
System.out.print(a+" "+b);
while(stack.size()!=0){
System.out.print(" ");
a=b;
b=stack.pop();
spend1+=p[a][b].value1;
spend2+=p[a][b].value2;
System.out.print(b);
}
System.out.print(" "+spend1+" "+spend2);
}
public static int f(){
int min,num = -1,min2;
min=MAX+1000;
min2=MAX+1000;
for(int i=0;i<n;i++){
if(visited[i]==0){
if(cost[i].value1<min){
num=i;
min=cost[i].value1;
min2=cost[i].value2;
}
else if(cost[i].value1==min){
if(cost[i].value2<min2){
num=i;
min=cost[i].value1;
min2=cost[i].value2;
}
}
}
}
return num;
}
}
class Path{
int value1;
int value2;
Path(int v1,int v2){
value1=v1;
value2=v2;
}
}