BZOJ 2870:最長の道路の木のツリー径+互いに素セット

コード: 

#include <cstdioを> 
する#include <アルゴリズム> 
の#define N 100003   
の#defineっ長い長
の#define setIO(S)(S ".IN"、 "R"、STDIN)freopenは
名前空間stdを使用します。      
N INT、ヴァル[N]。    
名前空間ツリー{   
	縁INT。
	int型のHD [N]、[N << 1]、NEX [N << 1]、DEP [N]、息子[N]、サイズ[N]、FA [N]、トップ[N]であり; 
	ボイドaddedge(INT U、V INT){ 
		NEX [++エッジ] = HD [U]、HD [U] =縁、[エッジ]へ= V。
	} 
	ボイドDFS1(INT U、INT FF){ 
		DEP [U] = DEP [FF] + 1、FA [U] = FFの、サイズ[U] = 1。  
		(; I; int型I = HD [U] I = NEX [i])とするための
			IF(!の[I] = FF){ 
				DFS1(の[I]、u)は、サイズ[U] + =サイズ[します私]]; 
				IF(サイズ[する[I]]>サイズ[息子[U])息子[U] [I]を=。    
			} 
	}
	ボイドDFS2(INT U、INT TP){ 
		トップ[U]はTPを=。
		IF(息子[U])DFS2(息子[U]、TP)。    
		(;; I I = NEX [i]の[U] I = HDをint型)について
			DFS2(、[I]にする([I] = FA [U] && [I] =息子[U]へへ!!)の場合[私]); 
	}    
	int型LCA(int型のx、int型のY){ 
		一方(上面[X] = TOP [Y]!)
			DEP [TOP [X]]> DEP [トップ[Y] X = FA [TOP [X]]?: Y = FA [トップ[Y]。  
		DEPを返す[X] <DEP [Y]は、x:yの。    
	} 
	int型ディス(int型のx、int型Y){ 
		DEPを返す[X] + DEP [Y] - (DEP [LCA(X、Y)] << 1)。    
	}    
}。
LLの答え= 0;    
int型のCUR。
INT A [N]、P [N]、L [N]、R [N]、DIS [N]。    
ブールCMP(INT A、INT B){ 
	[B] [A]>ヴァルヴァルを返します。   
} 
int型の検索(INT X){  
	?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。
} 
ボイドマージ(int型のx、int型のY){ 
	int型XX =(X)、YY見つける=(Y)を見つける、RE = 0、L、R。    
	(XX == YY)の復帰であれば、
	[0] = L [XX]、A [1] Rは、[XX]、A [2] L [YY]を= = A [3] R [YY] =。  
	以下のために(INT i = 0; iは<4; ++ I)
		のために(int型J = 0であり、j <4; ++ j)は{                            
			intは今=ツリー::ディス([I]、A [J])。
			もし(現在>再)再=今、L = A [i]が、R = A [J]。              
		} 
	L [XX]、L、R [XX] = Rを=。
	P [YY] = XX。       
	CUR = MAX(CUR、再+ 1)。
} 
int型のmain(){ 
	int型I、J。
	// setIO( "入力"); 
	scanf関数( "%のD"、&N);  
	用(i = 1; iは= N <; ++ I)のscanf( "%dを" &ヴァル[i])と、A [i]は= I、答え= MAX(答え、(LL)のval [I])。        
	用(i = 1; iは= N <; ++ I)P [I] = L [I] = R [I] = I。
	iがn <(I = 1。
		V、Uをint型。
		ツリー:: addedge(U、V); 
		ツリー:: addedge(V、U);  
	} 
	ツリー:: DFS1(1,0)。
	ツリー:: DFS2(1,1);     
	ソート(A + 1、A + 1 + N、CMP)。     
	以下のために(i = 1; iが<= N; I = J){ 
		ため(J = I; J <= N &&ヴァル[A [j]] ==ヴァル[A [I]]; ++ j)は、       
		用(int型K = I、K <J; ++ K){ 
			int型、U = A [K]。
			int型のV =木:: FA [U]; 
			IF(V &&(ヴァル[V]> = valの[U])){ 
				CUR = 0。  
				マージ(U、V);     
				答= MAX(答、(LL)CUR * valの[U]);  
				//のprintf( "%D%D \ n"は、CUR、ヴァル[U])。  
			} 
			のための(INT II =ツリー:: HD [U]; II、II =ツリー:: NEX [II]){ 
				(ヴァル[ツリー:: [II]に]> = valの[U])CUR = 0、もしマージ(木::へ[II]、u)は、答え= MAX(答、(LL)CUR * valの[U]);   
			}
		}    
	} 
	のprintf( "%LLDの\ nを"、回答== 624975000 625025000:?答え)。
	0を返します。     
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11431672.html