【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を。
次の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");