BZOJ 2870:分割統治最長の道路側の木

mxdep初期値があるべき-1最低限を満たしていない可能性があるため、二重ポインタに注意してください。 

コード: 

書式#include <cstdioを> 
書式#include <文字列>  
書式#include <マップ>
書式#include <CStringの> 
書式#include <ベクトル> 
書式#include <セット>  
書式#include <アルゴリズム> 

#define N 2000007
#define Fiの最初の
#define SE秒
#define LL長い長いです
#define INF 0x3f3f3f3f   
make_pairの#define MK(x、y)は(x、y)は     

名前空間stdを使用。  

名前空間IO {  

    空setIO(文字列s) 
    {
        = S +内の文字列「インチ」。 
        = S +アウト文字列 "アウト。"; 
        freopenは(in.c_str()、 "R"、標準入力)。 
        // freopenは(out.c_str()、 "W"、STDOUT)。 
    } 

}。  

int型nは、しかし、 
INTヴァル[N]。       
構造体のエッジ{
    int型のNEXに、ワット。    
} E [N << 1]、エッジ[N << 1]。     
INT edges1 = 1、edges2 = 1、HD [N]、[N]を事前。     
LL ANS;   

ボイド追加(int型のx、int型のy、int型Z) 
{
    E [++ edges1] .nex = HD [x]は、HD [X] = edges1、E [edges1] .TO = Y、E [edges1] .W = Z。    
}      

ボイドadd_c(int型のx、int型のY) 
{
    エッジが[++ edges2] .nex = [x]は、予め予備[X] = edges2、エッジ[edges2] .TO = Y。         
}  

無効リビルド(int型のx、int型FA) 
{ 
    int型FF = 0;        
    (; I; iは=エッジ[i]は.nex INT I =プレ[X])のために 
    {
        INT Y =エッジ[I] .TO。  
        (Y == FA)が継続する場合。     
        (もし!FF) 
        {
            (X、Y、1)を加え、 
            追加(Y、X、1)。          
            FF = X。   
        }
        そうしないと 
        {
            int型TMP = ++すべて。    
            ヴァル[TMP] = valの[X]。     
            (FF、TMP、0)を追加し、(TMP、FF、0)を加えます。    
            追加(TMP、Y、1)、追加(Y、TMP、1)。 
            FF = TMP;      
        }     
        (Y、X)を再構築します。   
    }
} 

対<整数、整数> LS [N]、RS [N]。     
int型LSC、RSC。      

ブールCMP(対<整数、整数> A、対<整数、整数> B) 
{
    (A.fi == B.fi)であれば、戻りA.se <B.se。   
    他のリターンA.fi <B.fi。 
}   

BOOL VIS [N << 1]。   
INTサイズ[N]、MX。    
int型RT1、RT2、エド、totsz。 

無効DFS1(int型のx、int型FA) 
{           
    サイズ[X] = 1。 
    (INT I = HD [X]; I; I = E [I] .nex)のために 
    {
        INT Y = E [I] .TO。  
        (Y == FA)が継続する場合。   
        もし(VIS [i])と続けます。   
        DFS1(Y、X)。      
        INT今= MAX(サイズ[Y]、totszサイズ[Y])。      
        (今の<mx)の場合 
        {
            mxは今=。 
            RT1 = X、RT2 = Y。  
            ED = I;   
        }   
        サイズ[X] + =サイズ[Y]。   
    }
}

DFS2ボイド(あなたはあなたMIは、あなたが、あなたをTYP DEP、簡単です、取得) 
{   
    もし(標準== 1) 
    {
        LS [LSC ++] = MK(私、DEP);   
    } 
    そうしないと 
    {
        RS [++ RSC] = MK(MI、DEP)。 
    }   
    (INT I = HD [X]; I; I = E [I] .nex)のために 
    {
        INT Y = E [I] .TO。     
        もし(Y == FA || VIS [i])と続けます。    
        DFS2(Y、Xの分(I、ヴァル[Y])DEP + E [I] .W、タイプ)。                         
    }
} 

無効Divide_And_Conquer(int型x)は、
{        
    (totsz == 1)に戻った場合。     
    RT1 = RT2 = ED = 0、MX = infファイル。       
    DFS1(X、0);      
    ビュー[ED] =程度[ED ^ 1] = 1。  
    LSC = RSC = 0。      
    DFS2(rt1,0、ヴァル[RT1]、0,0)。     
    DFS2(rt2,0、ヴァル[RT2]、0,1)。      
    幸いにも(LS + 1つの+ 1つの+ LS CCA、CMP)。    
    ソート(RS + 1、RS + 1つの+ RSC、CMP)。        
    int型mxdep、PTR。 
    mxdep = -1、PTR = RSC。          
    用(INT I = LSC; I> = 1;  -  I) 
    {
        一方、(PTR && RS [PTR] .fi> = LS [I] .fi) 
        {
            mxdep = MAX(mxdep、RS [PTR] .SE)、 -  PTR。   
        }
        ANS = MAX(ANS、(LL)((LL)mxdep + E [ED] .W + LS [I] .SE + 1)* LS [I] .fi)。                        
    }    
    mxdep = -1、PTR =皮下。 
    用(INT I = RSC; I> = 1;  -  I) 
    {
        一方、(PTR && LS [PTR] .fi> = RS [I] .fi) 
        {
            mxdep = MAX(mxdep、LS [PTR] .SE)。 
            --ptr;      
        }             
        LL TMP =(LL)(1LL * mxdep + E [ED] .W + RS [I] .SE + 1)* RS [I] .fi。   
        年= MAX(年TMP);      
    }     
    INT szrt1 = totszサイズ[RT2]。       
    INT szrt2 =サイズ[RT2]。   
    int型tmprt1 = RT1、RT2 tmprt2 =;    
    totsz = szrt1。      
    Divide_And_Conquer(tmprt1)。         
    totsz = szrt2。   
    Divide_And_Conquer(tmprt2)。           
}

メインint型() 
{ 
    // IO :: setIO( "入力");  
    私は、jはint型。   
    scanf関数( "%のD"、&N);   
    scanf関数( "%dの"、およびヴァル[i])と、ANS = MAX(ANS、(LL)のval [I]);(; <I = N ++ I I = 1の)のために     
    INT X、Y。   
    以下のための式(I = 1、I <N; ++ I) 
    {
        scanf関数( "%D%D"、およびX&Y)。    
        add_c(x、y)は、add_c(Y、X)。 
    }    
    TOT = N。     
    (1,0)を再構築します。    
    totsz =アップ。         
    Divide_And_Conquer(1)。    
    printf( "%のLLD \ n" は、ANS)。   
    0を返します。 
}

  

おすすめ

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