B-旅行
题意: 给定图, 求 max{ 任取三个点(起点 → 中转 → 终点)的最短路径长度 }
起点 → 中转 → 终点 ⇔ (中转 → 点1) + (中转 → 点2)
枚举中转点c, dijkstra求出c到其他点的最短距离, 在这些最短距离中选择两个最大的即可
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.*;
public class Main {
/*
给定图,求 max{ 三个点(起点->中转->终点)的最短路径长度 }
*/
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in), 65535);
static StreamTokenizer st = new StreamTokenizer(bf);
static int I() throws IOException {
st.nextToken();
return (int) st.nval;
}
public static void main(String[] args) throws Exception {
int t = I();
while (t-- > 0) {
solve();
}
}
static void solve() throws Exception {
int n = I(), m = I();
List<int[]>[] graph = new List[n + 1];
Arrays.setAll(graph, k -> new ArrayList<>());
for (int i = 0; i < m; i++) {
int a = I(), b = I(), c = I();
graph[a].add(new int[]{b, c});
graph[b].add(new int[]{a, c});
}
int ans = -1;
for (int c = 1; c <= n; c++) {//枚举中转点
int[] dist = dijkstra(graph, c);// 求中转点到其他点的最短路长度
//找两个最长的
Arrays.sort(dist);
List<Integer> l = new ArrayList<>();
for (int i = n; i >= 1; i--) {
if (dist[i] != Integer.MAX_VALUE / 2 && i != c) {
l.add(dist[i]);
if (l.size() == 2) break;
}
}
if (l.size() == 2) ans = Math.max(ans, l.get(0) + l.get(1));
}
System.out.println(ans);
}
static int[] dijkstra(List<int[]>[] graph, int start) {
int n = graph.length;
int[] dist = new int[n];
Arrays.fill(dist, Integer.MAX_VALUE / 2);
dist[start] = 0;
Queue<V> queue = new PriorityQueue<>(Comparator.comparingInt(a -> a.w));
queue.add(new V(start, 0));
while (!queue.isEmpty()) {
V cur = queue.poll();
if (cur.w > dist[cur.v]) continue;
for (int[] e : graph[cur.v]) {
if (dist[e[0]] > cur.w + e[1]) {
dist[e[0]] = cur.w + e[1];
queue.add(new V(e[0], dist[e[0]]));
}
}
}
return dist;
}
static class V {
int v;
int w;
public V(int v, int w) {
this.v = v;
this.w = w;
}
}
}