UVa 10048 - Audiophobia(Floyd变形)
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=989
题意:
输入一个C个点S条边(C≤100,S≤1000)的无向带权图,边权表示该路径上的噪声值。
当噪声值太大时,耳膜可能会受到伤害,所以当你从某点去往另一个点时,总是希望路上经过的最大噪声值最小。
输入一些询问,每次询问两个点,输出这两点间最优路径上的最大噪声值。
分析:
直接用floyd算法,但是要把加法改成max。
为什么可以这样做呢?不管是floyd算法还是dijkstra算法,都是基于这样一个事实:
对于任意一条至少包含两条边的路径i->j,一定存在一个中间点k,使得i>j的总长度等于i->k与k->j的长度之和。
对于不同的点k,i->k和k->j的长度之和可能不同,最后还需要取一个最小值才是i->j的最短路径。
把刚才的推理中“之和”换成“取最大值”,推理仍然适用。
代码:
1 import java.io.*; 2 import java.util.*; 3 import static java.lang.Math.*; 4 5 public class Main { 6 Scanner cin = new Scanner(new BufferedInputStream(System.in)); 7 final int INF = 0x3f3f3f3f; 8 final int UP = 100 + 5; 9 int G[][] = new int[UP][UP]; 10 11 void MAIN() { 12 for(int cases = 1; ; cases++) { 13 int c = cin.nextInt(); 14 int s = cin.nextInt(); 15 int q = cin.nextInt(); 16 if(c + s + q == 0) break; 17 for(int i = 0; i < c; i++) { 18 G[i][i] = 0; 19 for(int t = i+1; t < c; t++) G[i][t] = G[t][i] = INF; 20 } 21 for(int f, b, v, i = 0; i < s; i++) { 22 f = cin.nextInt() - 1; 23 b = cin.nextInt() - 1; 24 v = cin.nextInt(); 25 G[f][b] = G[b][f] = min(G[b][f], v); 26 } 27 28 for(int k = 0; k < c; k++) { 29 for(int i = 0; i < c; i++) { 30 for(int j = 0; j < c; j++) { 31 G[i][j] = min(G[i][j], max(G[i][k], G[k][j])); 32 } 33 } 34 } 35 36 if(cases > 1) System.out.println(); 37 System.out.printf("Case #%d\n", cases); 38 for(int f, b, i = 0; i < q; i++) { 39 f = cin.nextInt() - 1; 40 b = cin.nextInt() - 1; 41 if(G[f][b] == INF) System.out.println("no path"); 42 else System.out.println(G[f][b]); 43 } 44 } 45 } 46 47 public static void main(String args[]) { new Main().MAIN(); } 48 }