例题11-5 噪音恐惧症(Audiophobia, UVa10048)

欢迎访问我的Uva题解目录 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题11-5 噪音恐惧症(Audiophobia, UVa10048)_第1张图片

题意解析

输入一个C个点S条边(C≤100,S≤1000)的无向带权图,边权表示该路径上的噪声值。当噪声值太大时,耳膜可能会受到伤害,所以当你从某点去往另一个点时,总是希望路上经过的最大噪声值最小。输入一些询问,每次询问两个点,输出这两点间最大噪声值。

算法设计

参照《算法竞赛入门经典(第2版)》中的提示:

本题的做法十分简单:直接用floyd算法,但是要把加法改成min,min改成max。为什么可以这样做呢?不管是floyd算法还是dijkstra算法,都是基于这样一个事实:对于任意一条至少包含两条边的路径 i − > j i->j i>j,一定存在一个中间点k,使得 i − > j i->j i>j的总长度等于 i − > k i->k i>k k − > j k->j k>j的长度之和。对于不同的点k, i − > k i->k i>k k − > j k->j k>j的长度之和可能不同,最后还需要取一个最小值才是 i − > j i->j i>j的最短路径。把刚才的推理中“之和”与“取最小值”换成“取最小值”和“取最大值”,推理仍然适用。

C++代码

#include
using namespace std;
int C,S,Q,graph[105][105];
const int INF=0x3fffffff;
int main(){
    for(int ii=1;scanf("%d%d%d",&C,&S,&Q)&&C!=0;++ii){
        printf("%sCase #%d\n",ii>1?"\n":"",ii);
        for(int i=0;i<C+1;++i)
            for(int j=0;j<C+1;++j)
                graph[i][j]=INF;
        int a,b,c;
        while(S--){
            scanf("%d%d%d",&a,&b,&c);
            graph[a][b]=graph[b][a]=c;
        }
        for(int k=1;k<C+1;++k)
            for(int i=1;i<C+1;++i)
                for(int j=1;j<C+1;++j)
                    graph[i][j]=min(graph[i][j],max(graph[i][k],graph[k][j]));
        while(Q--){
            scanf("%d%d",&a,&b);
            if(graph[a][b]==INF)
                puts("no path");
            else
                printf("%d\n",graph[a][b]);
        }
    }
    return 0;
}

你可能感兴趣的:(算法竞赛入门经典,-,Uva)