洛谷題解UVA 10048【騒音恐怖症Audiophobia】

1720 ワード

【題意】
パス上のノイズ値を表す、(C)個の点(S)個のエッジ((C<=100))((S<=1000))個の無方向帯域重みマップを入力します.ノイズが大きすぎると、耳膜が損傷を受ける可能性があるので、ある点から別の点に行くときは、道を通るノイズの最大値が最小になることを常に望んでいます.いくつかの問い合わせを入力し、2つのポイントを尋ねるたびに、この2つのポイント間の最大ノイズ値が最小の経路を求めます.最大ノイズ値を出力
【アルゴリズム】
\(Floyd\)
【分析】
この問題のやり方は非常に簡単です:直接(Floyd)アルゴリズムを使って、しかし(+)を(min)、(min)を(max)に変えます.
どうしてこんなことができるのですか.ほとんどの問題解は証明されていません.ここでは証明過程を示します.
  • 証明プロセス
  • (Floyd)または(Dijkstra)アルゴリズムは、少なくとも2つのエッジを含む任意のパスi->jに対して、kの合計長さがi->ji->kの長さの和に等しいように、ある中間点k->jが必ず存在するという事実に基づいている.異なる点k,i->kk->jの長さの和が異なる場合があり、最後に最小値を取る必要があるのがi->jの最短パスである.さっきの推理で「の和」と「最小値をとる」を「最小値を取る」と「最大値を取る」に変えても、推理は適用されます.
    【コード】
    #include
    using namespace std;
    int n,m,Q;
    int g[110][110];
    int T;
    inline int read()
    {
        int tot=0;
        char c=getchar();
        while(c'9')
            c=getchar();
        while(c>='0'&&c<='9')
        {
            tot=tot*10+c-'0';
            c=getchar();
        }
        return tot;
    }
    int main()
    {
        n=read();m=read();Q=read();
        while(1)
        {
            T++;
            memset(g,0x3f,sizeof(g));
            for(int i=1;i<=m;i++)
            {
                int x=read(),y=read(),z=read();
                g[x][y]=z;
                g[y][x]=z;
            }
            for(int k=1;k<=n;k++)
            {
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=n;j++)
                    {
                        g[i][j]=min(g[i][j],max(g[i][k],g[k][j]));
                    }
                }
            }
            cout<

    転載先:https://www.cnblogs.com/hulean/p/11128628.html