hdoj3534(木DPの数、木の直径を求めて)

トピックリンクします。https://vjudge.net/problem/HDU-3534

問題の意味:木、木要求最長距離(直径)、およびそのような距離の数所与。

考える:ちょうど直径場合は、2つのDFSを使用することができます。しかし、今uはuが最も長い距離にリーフノードをルートとするサブツリーに記録されているDP1 [U]で、最長距離の番号を必要とする、DP2は、[U]は、これらの二つの最長の距離、比較の数を表します。維持しやすいです。DFS回答更新プロセス、ANS1で表されるツリーの直径は、ANS2は、直径の数、DP1 [V] + W + DP1 [U]> ANS1更新を示しています。

ACコード:

書式#include <cstdioを> 
する#include <アルゴリズム>
 使用して 名前空間はstdを、

const  int型 MAXN = 1E4 + 5 
typedefの長い 長いLL。
int型N、CNT、ヘッド[MAXN]。
【MAXN] ANS1、ANS2、DP1 [MAXN]、DP2 LL。

構造体ノード{
     int型NEX、W、V、。
}エッジ[MAXN << 1 ]。

ボイド ADDE(int型 U、int型、VをINT W){
    エッジ[ ++ CNT] .V = V。
    エッジ[CNT] .W = W。
    エッジ[CNT] .nex = 頭部[U]。
    ヘッド[U] = CNT。
}

ボイド DFS(int型、Uをint型FA)を{
    DP1 [U] = 0、DP2 [U] = 1 以下のためにint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V =エッジ[I] .V、W = エッジ[I] .W。
        もし(== FA V)続けます
        DFS(V、U);
        INT TMP = DP1 [V] + W。
        もし(TMP + DP1 [U]> ANS1){
            ANS1 = TMP + DP1 [U]。
            ANS2 = DP2 [U] * DP2 [V]。
        }
        そう であれば(TMP + DP1 [U] == ANS1){
            ANS2 + = DP2 [U] * DP2 [V]。
        }
        もし(TMP> DP1 [U]){
            DP1 [U] = TMP。
            DP2 [U] = DP2 [V]。
        }
        そう であれば(TMP == DP1 [U]){
            DP2 [U] + = DP2 [V]。
        }
    }
}

INT (){主
     ながら(〜のscanf(" %d個"、&N)){
        CNT = ANS1 = ANS2 = 0 以下のためにint型 i = 1 ; iは= N <; ++ I)
            ヘッド[I] = 0 ;
        以下のためにint型 i = 1 ; iがn <; ++ I){
             int型、U、V、W。
            scanf関数(" %D%D%D "、およびuは、&​​V、およびW)
            ADDE(U、V、W)。
            ADDE(V、U、W)。
        }
        DFS(10 );
        printf(" %LLD%LLD \ n " 、ANS1、ANS2)。
    }
    リターン 0 ;
}

 

 

ちなみに、コードのみ必要な直径のDFSで二回添付:

書式#include <cstdioを> 
する#include <アルゴリズム> 
書式#include <CStringの>
 使用して 名前空間はstdを、

typedefの長い 長いLL。
const  int型 MAXN = 1E4 + 5 int型N、CNT、ヘッド[MAXN]。
LLのDP1 [MAXN]、DP2 [MAXN]。

構造体ノード{
     int型NEX、W、V、。
}エッジ[MAXN << 1 ]。

ボイド ADDE(int型 U、int型、VをINT W){
    エッジ[ ++ CNT] .V = V。
    エッジ[CNT] .W = W。
    エッジ[CNT] .nex = 頭部[U]。
    ヘッド[U] = CNT。
}

ボイド DFS(int型、Uをint型FA)を{
    DP1 [U] = 0 int型フラグ= 0 以下のためにint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V =エッジ[I] .V、W = エッジ[I] .W。
        もし(== FA V)続けます
        フラグ = 1 
        DFS(V、U);
        もし(DP1 [V] + W> DP1 [U]){
            DP1 [U] = DP1 [V] + W。
            DP2 [U] = DP2 [V]。
        }
    }
    もし DP2 [U] =(フラグ!)U。
}

INT (){主
     ながら(〜のscanf(" %d個"、&N)){
        CNT = 0 ;
        以下のためにint型 i = 1 ; iは= N <; ++ I)
            ヘッド[I] = 0 ;
        以下のためにint型 i = 1 ; iがn <; ++ I){
             int型、U、V、W。
            scanf関数(" %D%D%D "、およびuは、&​​V、およびW)
            ADDE(U、V、W)。
            ADDE(V、U、W)。
        }
        DFS(10 );
        INT TMP = DP2 [ 1 ]。
        DFS(TMP、0 );
        printf(" %LLDする\ n " 、DP1 [TMP])。
    }
    リターン 0 ;
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/FrankChen831X/p/11705888.html