木の重心について話します

木の直径について話します


定義:

  ノードノードツリー最大サブツリーの最小数。

自然:

  1.元のツリーの1/2、重心までの2つとツリーを超えていないすべてのサブツリー・ノードの重力の結果として生じる中心を削除します。

  すべてのノードと重心の最小距離、重心が2つであり、それらは等距離2.ツリーである場合に、

  3.合併、2つの元のツリーパスの重心における重力の新しい中心による木の両側。

  4.ツリーがリーフノードを削除したり追加し、重心の片側のみが上方に移動します。

解決:

  多様を解決するための方法は、異なる定義および特性を使用しました:

  解決1.定義:

  SIZ [i]が表すノードI DP [i]は、iのサブツリーの大きさは、iノードstraightaway右点についてヴァル[i]は、最大ルートのサブツリーの大きさで表されているが、コードを説明します

  

インラインボイド DFSは(int型今、INT FA)
{ 
    SIZ [今] = valの[今]。
    DP [今] = 0 ;
    以下のためにint型 ; I I = I =ヘッド[今] [I] .nxt)
    { 
        int型 T = A [i]の.TO。
        場合(T FAを==)続けます
        DFS(今トン、); 
        SIZ [今] + = SIZ [T]。
        DP [今] = MAX(DP [今]、SIZ [T])。
    } 
    DP [今] = MAX(DP [今]、N- DP [今])。
    もし(DP [今] <DP [ANS])ANS =今; 
}

  2.自然の解決:

  一般的には十分な解決定義されていますが、時々、より便利で実用的な性質を解決。

  2の性質:我々はノードへのすべてのノードを処理することができる距離は、最小値をとります。

  どのように行うには、各ノードのノードから得ましたか?それは非常に簡単ですので、我々は最初の距離を扱うことができ、処理中に、DFSダウンでqwqルートにすべてのノード。

  。。SIZ [I]同上、F [i]はiはノードのすべての子ノードを表し、iは距離であり、ヴァル[I]同上は、[i]の右側に.val、1は、ルートノードとして設定されています。

  

インラインボイド DFS1(int型、今INTの FAを、INT 深い)
{ 
    SIZ [今] = valの[今]。
    [今] DEP = 深いです。
    以下のためにint型 ; I I = I =ヘッド[今] [I] .nxt)
    { 
        int型 T = A [i]の.TO。
        場合(T FAを==)続けます
        DFS1(T、今、深い + [I] .val)。
        SIZ [今] + = SIZ [T]。
        F [今] + = F [T] + SIZ [T] * [I] .val。
    } 
}

 

  プロセスのためにFは、その配列を認識:すべての子は今+距離を距離の現在のサブツリーのすべてのノードをtにTノード。

  これは、ルートから入手し、ルートノードの我々次いで再帰他のノードの距離を通って、宣伝以下の通りです。

  f [ now ] = f [ fa ] +( siz [ 根节点 ] - 2 * siz [ now ])* 边权;(now!= 根节点)

 

  理解如下:

  对于now的子节点,每个节点的距离减少了一个边权,总距离减少 siz [ now ] * 边权 ,对于非v子节点,每个节点距离增加了一个边权,总距离增加(siz[ 根 ]-siz [ now ])*边权

  

inline void dfs2(int now,int fa)
{
    if(now^root) f[now]=f[fa]+siz[1]-2*siz[now];
    if(f[now]<sum) res=now,sum=f[now];
    for(int i=head[now];i;i=a[i].nxt)
    {
        int t=a[i].to;
        if(t==fa) continue;
        dfs2(t,now); 
    }
}

 

  to be continue……

 

おすすめ

転載: www.cnblogs.com/knife-rose/p/11258403.html