题目连接:
http://www.lightoj.com/volume_showproblem.php?problem=1002
题目描述:
有n个城市,从0到n-1开始编号,n个城市之间有m条边,中心城市为t,问每个城市到中心城市的最小路径的花费,路径花费大小的定义为:一条路上花费最大的边的值。
解题思路:
Dijkstra的变形,用Dijkstra求出来的单源路径可以保证每条边都是最优的,所以最短路上的最长边就是所求。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 510; 8 const int INF = 0x3f3f3f3f; 9 int map[maxn][maxn], dist[maxn]; 10 void init () 11 { 12 int i, j; 13 for (i=0; i<maxn; i++) 14 for (j=0; j<maxn; j++) 15 if (i==j) 16 map[i][j] = 0; 17 else 18 map[i][j] = INF; 19 } 20 void dijkstra (int s, int n) 21 { 22 int i, j, vis[maxn]; 23 memset (vis, 0, sizeof(vis)); 24 25 for (i=0; i<n; i++) 26 dist[i] = map[s][i]; 27 vis[s] = 1; 28 29 for (i=1; i<n; i++) 30 { 31 int mini = INF, index; 32 for (j=0; j<n; j++) 33 if (!vis[j] && mini > dist[j]) 34 { 35 mini = dist[j]; 36 index = j; 37 } 38 if (mini == INF) 39 return ; 40 vis[index] = 1; 41 for (j=0; j<n; j++) 42 if (!vis[j]) 43 { 44 dist[j] = min(dist[j], max(map[index][j],dist[index]));//重点 45 } 46 } 47 } 48 int main () 49 { 50 int T, n, m, l = 1; 51 scanf ("%d", &T); 52 while (T --) 53 { 54 init (); 55 scanf ("%d %d", &n, &m); 56 while (m --) 57 { 58 int u, v, w; 59 scanf ("%d %d %d", &u, &v, &w); 60 if (map[u][v] > w)//有重边,选最优 61 map[u][v] = map[v][u] = w; 62 } 63 int t; 64 scanf ("%d", &t); 65 dijkstra (t, n); 66 printf ("Case %d: ", l ++); 67 for (int i=0; i<n; i++) 68 if (dist[i] != INF) 69 printf ("%d ", dist[i]); 70 else 71 printf ("Impossible "); 72 } 73 return 0; 74 }