【UVa习题】Audiophobia
放一下他在洛谷的链接:https://www.luogu.org/problemnew/show/UVA10048
第一次见到这道(坑)题是在刘汝佳的紫书(《算法竞赛入门经典》)上,为什么说这道题坑呢?因为这道题刘汝佳弄错了!!!
思路很简单,数据范围很小,所以可以使用Floyd算法的变形:对于从i到j的路径,枚举一个中间点k,假设d[i][j]存储i到j路径上的最大边权的最小值,那么max(d[i][k],d[k][j])就是从i到j,经过k的路径上的最大边权,这可能是一个答案,只需把d[i][j]更新成min(d[i][j],max(d[i][k],d[k][j]))就可以了。而紫书中印成了d[i][j]=max(d[i][j],min(d[i][k],d[k][j]))。这道题还有一个坑点,或者说两个,他是英文题不怪他,但输出格式那么严格就不太好了吧!千万要注意看清格式(其实主要是看不懂英文)。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 inline int get_num() { 8 int num = 0; 9 char c = getchar(); 10 while (c < '0' || c > '9') c = getchar(); 11 while (c >= '0' && c <= '9') 12 num = num * 10 + c - '0', c = getchar(); 13 return num; 14 } 15 16 const int maxn = 105, inf = 0x3f3f3f3f; 17 18 int dist[maxn][maxn]; 19 20 int main() { 21 int n, m, q, t = 0; 22 while (scanf("%d%d%d", &n, &m, &q) == 3 && n && m && q) { 23 memset(dist, inf, sizeof(dist)); 24 for (int i = 1; i <= n; ++i) dist[i][i] = 0; 25 for (int i = 1; i <= m; ++i) { 26 int u = get_num(), v = get_num(), w = get_num(); 27 dist[u][v] = dist[v][u] = w; 28 } 29 for (int k = 1; k <= n; ++k) 30 for (int i = 1; i <= n; ++i) 31 for (int j = 1; j <= n; ++j) 32 dist[i][j] = min(dist[i][j], max(dist[i][k], dist[k][j])); 33 ++t; 34 if (t != 1) putchar('\n'); 35 printf("Case #%d\n", t); 36 for (int i = 1; i <= q; ++i) { 37 int u = get_num(), v = get_num(); 38 if (dist[u][v] == inf) printf("no path\n"); 39 else printf("%d\n", dist[u][v]); 40 } 41 } 42 return 0; 43 }