Dijkstra算法
不带路径的:
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
final int INF = Integer.MAX_VALUE / 2;
int[][] grap = new int[n][n];
for (int i = 0; i < n; ++i) {
Arrays.fill(grap[i], INF);
}
for (int[] t : times) {
int x = t[0] - 1;
int y = t[1] - 1;
grap[x][y] = t[2];
}
int[] dis = new int[n];
boolean[] isVisited = new boolean[n];
Arrays.fill(dis, INF);
dis[k - 1] = 0;
for (int i = 0; i < n; i++) {
int x = -1;
for (int y = 0; y < n; y++) {
if (!isVisited[y] && (x == -1 || dis[x] > dis[y])) {
x = y;
}
}
isVisited[x] = true;
for (int y = 0; y < n; y++) {
dis[y] = Math.min(dis[y], dis[x] + grap[x][y]);
}
}
int ans = Arrays.stream(dis).max().getAsInt();
return ans == INF ? -1 : ans;
}
}
带路径的dijstra
class Solution {
public int networkDelayTime(int[][] times, int n, int k) {
final int INF = Integer.MAX_VALUE / 2;
int[][] grap = new int[n + 1][n + 1];
for (int i = 0; i <= n; ++i) {
Arrays.fill(grap[i], INF);
}
for (int[] t : times) {
int x = t[0];
int y = t[1];
grap[x][y] = t[2];
}
int[][] dis = new int[n + 1][2];//记录更新最短路径和前一个Node节点
boolean[] isVisited = new boolean[n + 1];
for (int i = 1 ; i <= n; i++) {
dis[i] = new int[]{INF, -1};
}
dis[k][0] = 0;
for (int i = 1; i <= n; i++) {
int x = -1;
for (int y = 1; y <= n; y++) {
if (!isVisited[y] && (x == -1 || dis[x][0] > dis[y][0])) {
x = y;
}
}
isVisited[x] = true;
for (int y = 1; y <= n; y++) {
if (dis[y][0] > dis[x][0] + grap[x][y]) {
dis[y][0] = dis[x][0] + grap[x][y];
dis[y][1] = x;
}
}
}
int ans = 0;
int p = k;
for (int i = 1; i <= n; i++) {
if (ans < dis[i][0]) {
ans = dis[i][0];
p = i;
}
}
StringBuilder str = new StringBuilder();
if (ans == INF) return -1;
while (p != k) {
str.append(p);
p = dis[p][1];
}
str.append(k);
System.out.println(str.reverse().toString());
return ans;
}
}
Floyd算法求最短路径以及保存path
class Solution {
private int n , k;
private int[][] grap;
private int[][] path;
public int networkDelayTime(int[][] times, int n, int k) {
this.n = n;
this.k = k;
final int INF = Integer.MAX_VALUE / 2;
grap = new int[n + 1][n + 1];
path = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j<= n; j++) {
if (i != j) {
grap[i][j] = INF;
} else {
grap[i][j] = 0;
}
path[i][j] = i;//初始化path为起点
}
}
for (int[] t : times) {
int x = t[0];
int y = t[1];
grap[x][y] = t[2];
}
floyd();
int ans = 0;
int e = 0;
for (int i = 1; i <= n; i++) {
if (ans < grap[k][i]) {
ans = grap[k][i];
e = i;
}
}
displayPath(k, e);
return ans == INF ? -1 : ans;
}
//求path路径
void displayPath (int start, int end) {
Stack<Integer> stack = new Stack<>();
int temp = end;
while (temp != start) {
stack.add(temp);
temp = path[start][temp];
}
stack.add(start);
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
//核心算法
void floyd() {
for (int i = 1; i <= n; i++) {
for (int x = 1; x <= n; x++) {
for (int y = 1; y <= n; y++) {
if (grap[x][y] > grap[x][i] + grap[i][y]) {
grap[x][y] = grap[x][i] + grap[i][y];
path[x][y] = path[i][y]; //点睛之笔,保存前驱
}
}
}
}
}
}