参考文章:https://www.liuchuo.net/archives/2359
思路看参考文章
一遍Dijkstra算法,用Dijkstra求边权最小的最短路径的条数,以及这些最短路径中点权最大的值。
rescue_queue[]-保存点权(救援队数目)
dis[i] -保存源点到i结点的最短路径
w[i]- 保存最大救援队数目
num[i]-保存从源点到i结点的最短路径个数若 dis[u] + e[u][v] <dis[v],更新dis[v],同时更新num[v]=num[u],w[v]= rescue_queue [v] +w[u];
如果dis[u] + e[u][v] == dis[v],还要更新num[v] +=num[u],而且判断一下是否权重w[v]更小,如果更小了就更新w[v] = rescue_queue [v] + w[u];
package pat;
import java.util.Arrays;
import java.util.Scanner;
/**
* 参考文章:https://www.liuchuo.net/archives/2359
*
* @author Charlie Yang
* 1、Dijkstra算法 -- 单源点最短路径问题
* 2、dis[i] -保存源点到i结点的最短路径 ,
* w[i]- 保存最大救援队数目 ,
* num[i]-保存从源点到i结点的最短路径个数
*
*/
public class Main{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int city = input.nextInt();// 城市数
int road = input.nextInt();// 道路数
int current = input.nextInt();// 当前城市
int destination = input.nextInt();// 目的地
input.nextLine();
String[] rescue = input.nextLine().split(" ");
int[] rescue_queue = new int[rescue.length];// 救援队数组,保存救援队数目
for (int i = 0; i < rescue.length; i++) {
rescue_queue[i] = Integer.parseInt(rescue[i]);
}
// System.out.println(Arrays.toString(rescue_queue));
int[] dis = new int[city];
int[] w = new int[city];
int[] num = new int[city];
int[][] e = new int[city][city]; // 边集
boolean[] vis = new boolean[city];
final int inf = 99999999;
Arrays.fill(vis, false);
Arrays.fill(num, 0);
Arrays.fill(dis, inf);
for (int i = 0; i < city; i++) {
Arrays.fill(e[i], inf);
}
for (int i = 0; i < road; i++) {
int fi, sec, adj;
fi = input.nextInt();
sec = input.nextInt();
adj = input.nextInt();
e[fi][sec] = e[sec][fi] = adj;
}
dis[current] = 0;
w[current] = rescue_queue[current];
num[current] = 1;
for (int i = 0; i < city; i++) {
int u = -1, minn = inf;
for (int j = 0; j < city; j++) {
if (vis[j] == false && dis[j] < minn) {
u = j;
minn = dis[j];
}
}
if (u == -1)
break;
vis[u] = true;
for (int v = 0; v < city; v++) {
if (vis[v] == false && e[u][v] != inf) {
if (dis[u] + e[u][v] < dis[v]) {
dis[v] = dis[u] + e[u][v];
num[v] = num[u];
w[v] = w[u] + rescue_queue[v];
} else if (dis[u] + e[u][v] == dis[v]) {
num[v] = num[v] + num[u];
if (w[u] + rescue_queue[v] > w[v])
w[v] = w[u] + rescue_queue[v];
}
}
}
}
System.out.printf("%d %d",num[destination],w[destination]);
}
}