存在する固有のパスのそれぞれに(重要な)ツリーのルートノード、
// DFS(ルート)DIS [ノード]は、ノードにルートノードから得られます
//そうでlen(U、V)= DIS [U]は+ DIS [V] - 2dis [LCA(U、V)]; // LCAはさておき、比較的単純な、しかし初期化関数を置くため、奇数のピット私は1hの
// Shichuishuitiごみ
#include <iostreamの> する#include <cstdioを> する#include <ベクトル> の#include <CStringの> する#include <ストリング> 名前空間STDを使用して、 const int型MAXN = 4E4 + 15。 N INT、M、和; // n個のノード、Mクエリ ブールrudu [MAXN]。 typedefは構造体 { int型V、値。 }縁; ベクター<エッジ>グレープ[MAXN]。 int型のクエリ[MAXN] [2]; // 0〜U / 1〜V [MAXN]編曲:INT; //每个查询的结果 ブールVIS [MAXN]。 int型の父[MAXN]。 INT DIS [MAXN]。 int型のfind(int型U) { (!U =父[U])であれば 父[U] =見つける(父[U]); 父を返す[U]; } ボイドTarjan(UをINT) { (I = 0をint型!; I =グレープ[U] .size(); ++ i)がために 、{ int型のV =グレープ[U] [i]は.V; //相邻节点 Tarjan(V); 父[V] = U; } VIS [U] = TRUE; 以下のために(INT i = 0; i = mの;!++ I) { int型ANS。 IF(U ==クエリ[I] [0] && VIS [クエリ[I] [1]]) { ANS =(クエリ[i]を[1])を見つけます。 [I] =のANS ARR。 } IF(U ==クエリ[I] [1] && VIS [クエリ[I] [0]]) { ANS =検索(クエリーを[I] [0])。 [I] =のANS ARR。 } } } //ブールフラグ[MAXN]。 無効DFS(int型のルート) { //フラグ[ルート] = TRUE; (I 0 = int型; I =グレープ[ルート] .size();!++ i)のための { int型Vが=グレープ[ルート] [I] .V。 和+ =グレープ[ルート] [I] .VALUE。 DIS [V] =合計。 DFS(V); 和- =グレープ[ルート] [I] .VALUE。 } } int型のmain() { int型のT、U、V。CIN >> T; 一方、(T--) { CIN >> N >> M。 (; iが<= N I ++ iは1 = INT)のために { 父[I] = I。 グレープ[I] .clear(); //清空图 } のmemset(rudu、偽、はsizeof(rudu))。 memsetの(クエリ、0、はsizeof(クエリ))。 memsetの(ARR、0、はsizeof(ARR))。 memsetの(VIS、偽、はsizeof(VIS)); エッジノードは、 のために(INT I = 0; I-N- = 1 ;!私++) { CIN U >> >> node.v node.value; rudu 【node.v] = trueに、 グレープ[U] .push_back(ノード); } //バンドエッジ重み値 のための(I = 0 int型、M = I ;! Iが++) { CIN >>クエリ[I] [0] >>クエリ[I] [1]; } ルートINT; (。; V <= N; INT 1 = V ++ V)のために (!rudu [V])IF { ルート= V; //ルート Tarjan(V); } // ARRストレージ親ノード 図の各ノードへのルートから// DFS距離 ため//(INT i = 0; !I = mの; ++ I) // coutの<< ARR [i]は<<てendl; ENDL、 ルートから各ノードまで//;和= 0 memset(DIS、0、はsizeof(DIS))。 //のmemset(フラグ、偽、はsizeof(フラグ))。 DFS(ルート)。 //(I = 1をint型++ I; iが<= n)のため // COUT << DIS [V] << ENDL。 (!; I = M ++ iは0 = INT)用 { 2 * DIS [i]はARR - COUT << DIS [クエリ[I] [0] + DIS [クエリ[I] [1] ] << ENDL。 } } }