トラック輸送問題解決

https://i.cnblogs.com/EditPosts.aspx?opt=1

被験者の要件は貨物輸送の最大量yを指すようにXを指すことができる見つけることであり、換言すれば、yにxをできるだけ大きく最小エッジの重みをパスを見つけることです。

最短と同様にの一見の考えではなく、X、Yが明らかに最短時間外の上に走っている場合、データは、大きすぎます。

実際に見つけるのは、難しいことではありません、我々は彼らがマップが再び木に退化し、元のマップの接続性を確保するために最大のイルカスパニングツリーを作るせ、できるだけ大きく選択する必要があります。

乗算プロセス中ように、右側の最小値は、時間の複雑さはO(Qの*のLOGN)であります

コードは少し長いですが、彼らはテンプレートです

#include <cstdioを> 
する#include <iostreamの> 
する#include <アルゴリズム>
 の#define N 1000000
 の#define MAXINT 0x7f7f7f7f
 使用 名前空間STD。
int型N、M、Q、TOT。
INT FIR [N]、[N]に、NEX [N]、DIS [N]。
INT F FA [N]、[N] [ 25 ]、深い[N]、D [N] [ 25 ]。
BOOL VIS [N]。
構造体ノード{
     int型のX、Y、K。
} E [N]。
インラインボイド R(INTX){ 
    X = 0 チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 ')CH = GETCHAR()。
    一方、(CH> = ' 0 ' && CH <= ' 9 ')x =(x << 3)+(X << 1)+(CH ^ 48)、CH = GETCHAR()。
} 
インラインボイド追加(int型のx、int型の Y、int型K){//树上的无向边建立
    【へ ++ TOT = Y、NEX [TOT =モミ[X]、DIS [TOT] = K、 FIR [X] = TOTを、
    【へ ++ TOT] = xと、NEX [TOT =モミ[Y]、DIS [TOT] = K、FIR [Y] = TOT。
} BOOL CMP(ノードX、Yノード){//小さいソーティング大きいによって右側
     戻り XK> YK; 
} 
インラインINT ANC(INT X){//パスコンプレッサ
     IF(!FA [X] = X)FA [ X] = ANC(FA [X]);
     戻りFA [X]; 
} 
インラインINT DFS(INT X){//検索ツリーを、記録F [] [0] 
    VIS [X] = 1 ;
     int型I、V。
     以下のための(I = FIR [X]; V =に[I]、I; I = NEX [I]){
         IF(! {VIS [V])
            ディープ[V] =ディープ[X] + 1 ; 
            F [V ] [ 0] = X; 
            D [V] [ 0 ] = DIS [i]は、
            DFS(V); 
        } 
    } 
} 
インラインボイドCAL(){//乗算は、各祖先ノードと各ノードの祖先を取得します前記エッジ重みの経路に
     するためのINT I = 1 ; I <= 19 ; Iは++ のためにINT J = 1。 ; J <= N; J ++ ){ 
            F [J] [I] = F [F [J] [I - 1 ] [I- 1 ]、
            D [J] [I] =分(D [J] [I- 1 ]、D [F [J] [I- 1 ]] [I- 1 ]); / / D最小エッジ重量を記録し
        } 
} 
インライン INT(LCA INT X-、INT Y-){//答えを見つける
     IF([X-] [F 19!] = F [Y-] [ 19 は、それらがツリー等しくないない場合//])
         リターン - 。1 ;
     INT I、ANS = MAXINT;
     IF(ディープ[X] < ディープ[Y])スワップ(X、Y); //テンプレートLCA、最小要件の更新中のLCA方法以下
     (I = 19、I > = 0 ; i-- ){
         IF(ディープ[F [X] [I]]> = ディープ[Y]){ 
            ANS = 分(ANS、D [X] [I]); 
            X = F [X] [I]; 
        }
        もし(x == y)は戻りANS; 
    } 
    のための(I = 19 ; I> = 0 ; i-- であれば(!F [x]は[I] = F [Y] [I]){ 
            ANS = 分(ANS、分(D [X] [I ]、D [Y] [I]))。
            X = F [X] [I]。
            Y = F [Y] [I]。
        } 
    ANS =分(ANS、分(D [X] [ 0 ]、D [Y] [ 0 ]));
    戻るANSを。
} 
int型のmain()
{ 
    int型I、J、X、Y、K、B。
    R(n)は、R(M)。
    (i = 1 ; I <= M; iは++ 
        R(E [I] .X)、R(E [I]・Y)、R(E [I]・K)。
    ソート(E + 1、E + 1 + M、CMP)。
    (i = 1 ; iが<= N; iは++)FA [I] = I。
    (i = 1 ; I <= M; iは++ ){//最大生成树模板
        A = ANC(E [i]は.X)、B = ANC(E [I] .Y)。
        もし(== b)は継続します
        (E [I] .X、E [i]は.Y、E [I]・K)を加えます。
        FAは、[A] = Bと、
    } 
    ため(i = 1 ; iが<= N; iは++ ){
         場合(! I。それはであるかどうかを確認するために各ポイントを横断する、I] [VIS)できるだけ{//複数のツリー私たちは木を横断しました
            F [i]が[ 0 ] =
            D [i]が[ 0 ] = MAXINT。
            深い[I] = 1 
            DFS(I); 
        } 
    } 
    CAL()。
    R(Q)。
    一方、(q-- ){ 
        R(x)は、R(Y)
        printf(" %d個の\ n " 、LCA(X、Y))。
    } 
}

 

おすすめ

転載: www.cnblogs.com/quitter/p/11497017.html