P4180 [テンプレート]厳密に小さなスパニングツリー[BJWC2010]
これが最後の大規模なオープンINFがアップコピーINFの問題に対する解決策を見つけなければならないです
厳密に最小スパニングツリーと小さな違いは?
あるいは最小スパニングツリーは、ツリーの非エッジ側であります
(非ツリーコラージュ同じ時間で最大右側が大きい側を見つけた場合)最大ツリー頂点チェーンを見つけるために、両側にそれぞれ非ツリーエッジを列挙する
そしてその後、並べ木を乗算得ることができる最大と二番目の最小単位を更新します
書式#include <cstdioを> する#include <キュー> の#include <CStringの> の#include <cmath> の#include <スタック> の#include <アルゴリズム> 使用して 名前空間はstdを、 #defineっ長い長 の#define RGレジスタ のconst int型 N = 100000 + 5、M = 500000 + 5、INF = 0x3f3f3f3f 。 #define INF21474836.47億。 INTのN、M。 LL和 = 0LL、ANS = INF。 LLをP [N] [ 25 ]、MX [N] [ 25]、CM [N] [ 25 ]、DEP [N]。 BOOL 使用[M]。 テンプレート < クラス T> ボイド RD(T&X){ X = 0。INT W = 0。CHAR CH = 0 。 しばらく W | = CH ==(isdigit(CH)!)' - '、CH = getchar関数(); 一方、(isdigit(CH))X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR()。 X?= W - X:X; } LLヘッド[N]、TOT = 0; 構造体のエッジ{LLのV、NXT、W;} E [M << 1 ]。 ボイド追加(LL U、LLをV、のLL W){ E [ ++ TOT =(エッジ){V、ヘッド[U]} W;頭部[U]は= TOT。 } INT F [N]。 構造体ノード{ int型U、V、W。 // ブール演算子<(constのエッジ&A)のconst {Awの<Wリターン;} } ND [M]。 ブール CMP(ノードA、ノードB){ 戻り AW < BW;}; int型の検索(INT X){ 戻り F [X] == X X:F [X] = 検索(F [X]);} ボイドクラスカルを(){ 用(INT I = 1; iが<= N; ++ I)F [I] = I。 int型 CNT = 0 ; 以下のために(int型 I = 1、U、V、Wと、I <= M && CNT <N; ++ I){ U = ND [i]は.U、V = ND [I] .V、W = ND [I]。ワット; 場合(見つける(U)=!見つける(V)){ F [F [U] = F [V]。 和 + = ND [i]は.W、使用++ CNT、[I] = 1 。 (Uは、V、W)、追加(V、U、W)。 } } } ボイドDFS(U、LL FA LL){ P [U] [ 0 ] = FA。 DEP [U] = DEP [FA] + 1LL。 センチ[U] [0 ] = - INF。 用(; I I = 11、I =ヘッド[U]、V {E [I] .nxt) V = E [I] .V。 もし(== FA V)続けます。 MX [V] [ 0 ] = E [I] .W。 DFS(V、U); } } ボイド倍加(){ ため(int型 i = 1 ; iが= < 20 ; ++ i)が ため(INT J = 1 ; J <= N; ++ j)を{ P [j]は[I] Pは= [ P [j]は[I- 1 ]] [I- 1 ]。 MX [J] [i]は= MAX(MX [j]は[I- 1 ]、MX [P [j]は[I- 1 ]] [I- 1 ])。 CM [J] [I] = MAX(CM [j]は[I- 1 ]、CM [P [j]は[I- 1 ]] [I- 1 ])。 もし(MX [J] [I- 1 ]> MX [P [j]は[I- 1 ]] [I- 1 ])CM [J] [I] = MAX(CM [j] [i]は、MX [ P [j]は[I- 1 ]] [I- 1 ])。 そう であれば(MX [j]は[I- 1 ] <MX [P [j]は[I- 1 ]] [I- 1 ])CM [J] [I] = MAX(CM [j] [i]は、MX [J] [I- 1 ])。 } } LLのLCA(LLのB、LL){ 場合(DEP [A]>DEP [B])スワップ(B) 以下のために(int型 iは= 20、I> = 0 ; - i)が{ 場合(DEP [P [B] [I] <DEP [A])続けます。 B = P [B] [I]。 } 場合(== b)が返します。 以下のために(int型 iは= 20、I> = 0 ; - I){ 場合(P [A] [I] == P [B] [i])と続けます。P = [A] [I]、B = P [B] [I]。 } 戻り P [A] [ 0 ]。 } LLのQmaxと(LL U、LLをV、LL用MXX){ LL再 = - INF。 用(int型私は= 20、I> = 0 - ; I)の 場合(DEP [P [U] [I]]> = DEP [V]){ 場合(MXX = MX [U] [I]!)再= MAX(再度、MX [U] [I])。 他に再= MAX(再、CM [U] [i])と、 U = P [U] [I]。 } 戻り再。 } int型のmain(){ // freopenは( "in.txt"、 "R"、STDIN)。 memsetの(使用、0、はsizeof (使用されます))。 RD(n)は、RD(M)。 U、V、W LL; 以下のために(int型 I = 1 ; I <= M; ++ I){ RD(U)、RD(V)、RD(W)。 ND [I] = (ノード){U、V、W}。 } ソート(ND + 1、ND + 1 + M、CMP)。 クラスカル(); DEP [ 0 ] = 0 。 DFS(1、0 );倍加()。 用(RGのINT I = 1 ; I <= M; ++ I)の 場合(!使用[I]){ LL U = ND [i]は.U、V = ND [I] .V、W = ND [I ] .W。 LLのLCA = LCA(U、V)。 LLのMXU = Qmaxと(U、LCA、W)、MXV = Qmaxと(V、LCA、W)。 ANS =分(ANS、和-MAX(MXU、MXV)+ W)。 } のprintf(" %のLLD " 、ANS)。 リターン 0 ; }