XSY 2018] [NOIP2013トラック輸送

【NOIP2013]運送

説明

国営 のnから数え都市、1〜nは、都市間にあるM双方向道路。すべての道は重量制限と呼ばれる車の重量制限があります。ありますQトラックが商品の輸送に、ドライバは、複数の商品を輸送するまで、車両の重量制限を超えることなく、すべての車を知ってほしいです。

入力

整数の空間によって分離された最初の2行 のN M、Aが所有表し、n個の都市とm個の道路。
次のM個の行それぞれ3整数X Y Z、スペースで区切られた2つの整数の間には、それぞれ表すために都市のx個の都市Y数の重量制限有するZ道路。注意:xは等しくないyは、二つの都市間の道路の数であってもよいです。
整数ある次の行qは、発現のQトラックが貨物を必要とします。
のQ二つの整数の線X Yの間には、スペースで区切られた、からトラックの必要性を表すXに都市交通貨物Y注意を払って、都市:xは等しくないYを。

出力

総出力 Qの行、各トラックのための表す各整数は、最大荷重です。トラックが先、出力に到達できない場合は  - 1

サンプル入力

43 
1 2 4 
2 3 3 
3 1 1 
3 
1 3 
1 4 
1 3

サンプル出力

3 
-1 
3

ヒント

30%データ、1 N- 1000年1 M 10000 1 Q 1000年
のためにデータの60%、1 N- 1000年1 M 50000 1 Q
のためにデータの100%、1 N- 10000 1 M 50000 1つのQ 30000 0 Z 100000

問題の解決策のアイデア

図の少なくとも一方の側の経路上の2点間の最大スパニングツリーがない場合、各エッジ値がそのエッジに等しい値よりも大きい前記第一、この図では、特定の経路が、存在します。

だから、あなたは彼らに最大スパニングツリーを尋ねると、最小を維持するためにLCAを使用している場合。

時間複雑:O(nlogn)

 

書式#include <iostreamの> 
の#include <cstdioを> 
する#include <アルゴリズム> 
std名前空間を使用しました。
構造体データ{ 
    int型X、Y、V。
} T [50001]、D [20001]。
N INT、M、S [10001] [21] [10001] [21] F、FA [10001]、H [10001]、CNT、FX、FY、ANS、P [10001]、ID [10001] X 、Y。
BOOL CMP(データA、データB){ 
    戻りAV> BV。
} 
int型の父親(INT A){ 
    IF(FA [A] = A!)FA [A] =父(FA [A])。
    FA [A]を返します。
} 
{(int型B、int型のC INT)ボイド追加
    CNT ++。
    D [CNT] .X = B。
    D [CNT] .Y = hの[A]。
    D [CNT] .V = C。
    H [A] = CNT。
} 
ボイドDFS(INT A){ 
    (I = 1 int型私は++; iが= 20 <)のために{ 
        F [A] [I] = F [F [A] [I-1]] [I-1];
        S [A] [I] =分(S [A] [I-1]、S [F [A] [I-1]] [I-1])。
    } 
    ため(; I; I = hの[A] int型I = D [i]は.Y){ 
        IF(!pを[D [i]は.X]){ 
            P [D [i]は.X] = Pは[A ] +1。
            F [D [i]は.X] [0] =。
            S [D [i]は.X] [0]、Dが= [I] .V。
            ID [D [i]は.X] = ID [A]。
            DFS(D [i]の.X)。
        } 
    } 
} 
ボイドLCA(INT A、INT B){ 
    IF(P [A]> P [B]){ 
        (I = 20 int型; I> = 0; I - )は{ 
            IF(P [F A ] [I]]> = P [B]){ 
                ANS =分(ANS、S [A] [I])。
                = F [A] [I]。
            } 
        } 
    } 
    (P [A] <P [B]){もし 
        { - (I; = 0、I iは20 = INT)のために>
            {(= P [A]、P [I] [B] [F])場合>
                ANS =分(ANS、S [B] [I])。
                B = F [B] [I]。
            } 
        } 
    } 
    (i = 20 int型; I> = 0; I - )は{ 
        IF(!F [A] [I] = F [B] [I]){ 
            ANS =分(ANS、S [A] [私]); 
            ANS =分(ANS、S [B] [I])。
            = F [A] [I]。
            B = F [B] [I]。
        } 
    } 
    (= B!){もし
        ANS =分(ANS、S [A] [0])。
        ANS =分(ANS、S [B] [0])。
    } 
} 
int型のmain(){ 
    scanf関数( "%D%dの"、&N、&M)。
    scanf関数( "%D%D%D"、およびT [i]は.X、&T [i]は.Y、&T [i]は.V)(; I <= M I ++はiは1 = INT)のために、
    以下のために(INT I = 1; I <= M。
    以下のために(INT i = 1; iが<= N; iは++)FA [I] = I。
    ソート(T + 1、T + M + 1、CMP)。
        FY =父(T [i]の.Y)。
        もし(FX = FY!){ 
            FA [FX] = FY。
            追加(T [i]を.X、T [i]を.Y、T [i]は.V)。
            ([I] .V T [i]の.Yを、T [i]を.X、T)を追加。
        } 
    } 
    {(; iが<= N I ++は、I = 1 INT)のための
        (ID [I]!){場合
            のP [I] = 1。
            ID [I] = I。
            DFS(I); 
        } 
    } 
    のscanf( "%dの"、&M)。
    {(; I <= M I ++はiは1 = INT)のための
        ANS = 10000000。
        scanf関数( "%dの%のD"、およびX&Y)。
        IF(ID [X] == ID [Y]){ 
            LCA(X、Y)
            printf( "%d個の\ n"、ANS)。
        }他のprintf( " - 1 \ n");

 

  

 

おすすめ

転載: www.cnblogs.com/ez-syh/p/11615450.html