タイトル説明
好都合1..N番号N牛(2 <= N <=千)も便利1..Nの番号Nの牧草地間で放牧されています。最も好都合全ての、牛の私は、牧草地に放牧されています。
牧草地のいくつかの対は、牛が通過できるN-1双方向通路のいずれかによって接続されています。通路iは牧草a_iをとB_i(1 <= a_iを<= N、1 <= B_i <= N)を接続し、L_iを(1 <= L_iを<= 10,000)の長さを有します。
通路は、任意の二つの別個の牧草地の間、それらの間を移動通路のうちの正確に1つのパスが存在するように設定されています。このように、歩道には、ツリーを形成します。
牛は非常に社会的であり、しばしばお互いを訪問したいです。今まで急いで、彼らはあなたがそれらを牧草地の1 <= L_iを<=万組(クエリP1として与えられたそれぞれのペア、P2(1 <= P1 <= N間のパスの長さを計算することによって、彼らの訪問をスケジュールする手助けをしたいです1 <= P2 <= N)。
POINTS:200
N(2 <= N <= 1000)の牛がありますが、それらは同様にNの牧草地の歩行に1の番号が付けられ、Wに番号1。便宜上、私たちは、i番目の牧草地に牛の数iと仮定。
<1本のバーは、牛がパスAiとBiの牧草地までも、牧草地をi番目(1のこれらの道路の上を歩くことができます - 各2つの牧草地の間にいくつかの牧草地は、道路には、Nの合計を持って、双方向の道路で接続されています。 = a_iを<= N、1 <= B_i <= N)、その長さは、任意の2つの牧草地の間に1 <= L_iを<= 10,000、そして唯一のパスが構成されている道路の複数の接続されています。彼はすべての道路がツリーを構成することを述べました。
牛は非常に多くの場合、彼らは非常に不安。お互いに会いたいので、私はあなたが彼らの旅行を計画する際に役立つ願って、あなただけのP1を求めてのポイントにポイントの各ペア間のパスの長さ•Q(1 <Q <1000)を計算する必要があります、P2(1 <= P1 <= N、1 <= P2 <= N)。形で与えられます。
入力形式
* 1行目:二スペースで区切られた整数:NとQ
*行2..N:a_iを、B_i、およびL_iを:i線+ 1が3スペースで区切られた整数を含みます
*行N + 1..N + Qは:P1およびP2:各行には2スペースで区切られた牛が旅行したいとの間で二つの異なる牧草地を表す整数が含まれています
出力フォーマット
*行1..Qは:ライン私は、クエリ私に2つの牧草地間のパスの長さが含まれています。
サンプル入力と出力
4 2 2 1 2 4 3 2 1 4 3 1 2 3 2
2 7
説明/ヒント
クエリ1:牧草1と2の間の通路の長さ2を有しています。
問合せ2:7の全長のために、4と1の間に1つ、そして最後に1と2の間の1つ次いで、牧草地3と4との間の通路を通って移動します。
我々はすべて知っているフロイドの複雑さがある O(N ^ 3)O (N- 3 )が、我々はプルーニングすることができます。我々は、元のフロイド知る必要が DIST D I S T配列が初期化され inftyのの\ ∞をので、第二層ときに我々サイクル、電流If DIST(I、K)= \ inftyのD I S T (I 、K )= ∞はスキップすることができます。
#include <cstdioを> する#include <CStringの> に#define分(A、B)((A)<(B)(A)(B)?)使用して名前空間STD。 const int型 MAXN = 1E3; const int型 INF = 0x3f3f3f3f 。 INT D [MAXN + 1 ] [MAXN + 1 ]。 int型N、Q; インラインint型リード(){ int型、S = 0、W = 1 。 チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 ' ){ 場合(CH == ' - ' ){ W = - 1 。 } CH = GETCHAR()。 } 一方、(CH> = ' 0 ' && CH <= ' 9 ' ){ S = sの* 10 + CH- ' 0 ' 。 CH = GETCHAR()。 } 戻り S * W。 } int型のmain(){ memsetの(D、0x3fを、はsizeof(D))。 N = 読み取ります(); Q = 読み取り(); 以下のために(int型 iは= 1 ; iがNを<++、A、B、L 、{I) A =を読み取ります()。 B = 読み取ります(); L = 読み取ります(); D [A] [B] = D [B] [A] = L。 } のために(int型 = K 1、K <= N; ++ K) のための(int型 i = 1 ; iは= N <; ++ I){ 場合(D [i]が[K] == INF){ 続け; } のための(INT J = 1 ; J <= N; ++ j)は{ D [i]は[J] =分(D [i]は[J]、D [i]は[K] + D [k]は[J ]); } } のための(INT P1、P2; Q-- ;){ P1 = 読み取ります()。 P2 = リード()。 printf(" %d個の\ n " 、D [P1]、[P2])。 } 戻り 0 。 }