P1396レスキュー+最短ルート

アルゴリズム

最短経路+バリアント

アイデア

慎重に考えてみましょう。どのポイントでも、最大混雑度の最小値は、隣接するポイントの値と、それらの間のエッジの重みが最大値をとる必要があります。分!

 

このように、ボードのスラックがわずかに変更されている限り、つまり、元の合計だけを最大に変更して、問題ないようにすることができます。

 

また、この質問は無向グラフを構築する必要があることに注意してください!

コード

#include <cstdio> 
#include <algorithm> 
#include <cstring> 
#include <queue> 
using namespace std; 

const int M = 30001; 
inline int read(){ 
    int ret; bool flag = 0; char c; 
    while((c = getchar())<'0' || c> '9')flag ^ =!(c ^ '-'); ret = c ^ 48; 
    while((c = getchar())> = '0' && c <= '9')ret =(ret << 3)+(ret << 1)+(c ^ 48); 
    フラグを返す?-ret:ret; 
} 

キュー<int> Q; 
int fir [M >> 1]、nex [M]、go [M]、val [M]; 
int dis [M >> 1]、vis [M >> 1]; 
int n、m、a、b、tot; 

インラインvoid add_edge(int x、int y、int z)
{ 
    nex [++ tot] = fir [x]、fir [x] = tot、go [tot] = y、val [tot] = z;


    n = read(); m = read(); a = read(); b = read(); 
    for(int i = 1; i <= m; i ++)
    { 
        int x、y、z; 
        x = read(); y = read(); z = read(); 
        add_edge(x、y、z); 
        add_edge(y、x、z); 
    } 
    for(int i = 1; i <= n; i ++)dis [i] = 1e9 + 7; 
    dis [a] = 0; 
    Q.push(a); 
    vis [a] = 1; 
    while(!Q.empty())
    { 
        int Now = Q.front(); 
        Q.pop(); 
        int Go; 
        vis [Now] = 0; 
        for(int i = fir [Now]; i、Go = go [i]; i = nex [i])
        { 
            if(dis [Go]> max(dis [Now]、val [i]))
            {
                dis [Go] = max(dis [Now]、val [i]); 
                if(!vis [Go])Q.push(Go)、vis [Go] = 1; 
            } 
        } 
    } 
    if(dis [b] == 1e9 + 7)dis [b] = -1; 
    printf( "%d"、dis [b]); 
    0を返します。
}

  

  

 

#が含まれ 、<cstdioを>含める <アルゴリズム>含める <CStringの>含める <キュー>使用して名前空間はstdを、const int M = 30001 ; inline int read (){ int ret; bool flag = 0 ; char c; while ((c = getchar())< '0' || c> '9' )flag ^ =!(c ^ '-' ); ret = c ^ 48 ; while ((c = getchar())> = '0' && c <)ret =(ret << 3 )+(ret << 1 )+(c ^ 48 ); フラグを返す?-ret:ret; }キュー< int > Q; int fir [M >> 1 ]、nex [M]、go [M]、val [M]; int dis [M >> 1 ]、vis [M >> 1 ]; int n、m、a、b、tot; inline void add_edge(int x、int y、int z){nex [++ tot] = fir [x]、fir [x] = tot、go [tot] = y、val [tot] = z; } int main(void ){n = read (); m = read (); a = read (); b =読む(); for int i = 1 ; i <= m; i ++){ int x、y、z; x = 読み取り(); y = 読み取り(); z = 読み取り(); add_edge(x、y、z); add_edge(y、x、z); } for int i = 1 ; i <= n; i ++)dis [i] = 1e9 + 7 ; dis [a] = 0 ; Q.push(a); vis [a] = 1 ; while (!Q.empty()){ int Now = Q.front(); Q.pop(); int Go; vis [Now] = 0 ; for inti = fir [Now]; i、Go = go [i]; i = nex [i]){ if (dis [Go]> max (dis [Now]、val [i])){dis [Go] = max (dis [Now]、val [i]); if (!vis [Go])Q.push(Go)、vis [Go] = 1 ; }}} if (dis [b] == 1e9 + 7 )dis [b] = -1 ; printf("%d" 、dis [b]); 0を返します}

おすすめ

転載: www.cnblogs.com/ruanmowen/p/12727645.html