説明 - [ZJOI2007]の同期状態(ツリー構造)

説明 - [ZJOI2007]の同期状態(ツリー構造)

なぜDPを書くのか?、それはちょうど水の問題点されていません


フェイス質問

説明
小さなQ学習は、電子回路基板技術のトレーニングコースにはんだ付けされました。要素の数によって回路基板は、我々は、参照のノード、およびそのデジタル1,2,3 ....呼ぶかもしれません。各ノードは、ディスジョイント導体複数の、回路基板の任意の2つのノードのために回路基板に接続され、そして(パスは、2つの導体の配列を連結するための手段)一つだけのパスが存在しています。

回路基板上の特定の要素の存在下で、「トリガ」と呼ば 励起を操作する場合、ノードそれのそれぞれに接続されたワイヤを通過した励起電流を生成します。励磁電流を受信後の中間ノード、情報を取得し、それを広げ、ノードに接続する通電励磁電流を受信して​​いません。もはや転送される励磁電流を受けていない後にノード - 最後に、強烈な電流は、いくつかの「端末ノード」に到達します。

励磁電流導体を伝搬することは、励磁電流がTであるかかる時間によって、各エッジのために時間がかかり、そしてEすることができ
、受信ノードは、励起電流が瞬間であると考えることができる転送します。すなわち、同期保持状態-ボードは、現在得られた励磁回路ながら、各「終端ノード」を必要とします。構造は、現在の時間同期要件を満たしていないので、接続線の構成を変更することにより、必要とします。励磁電流は、接続ストリップ導体を介して一つの単位時間によって増加させることができるように、現在、小さな支柱QQは、支柱と、があります。Qは小さな同期状態何回小道具の最小使用が可能なすべての「エンド・ノード」となるようウィル?

INPUTの
木+のルート

出力

の最小数を表す整数

in.1
3
1
1 2 1
1 3 3

out.1
2

データ範囲と表記

100%のデータ、N <= 1E5、T <= 1E6

考え

主なアイデア

境界値を減らすことができないので、我々はiは、iが一定でないなどの長辺に接続されたノードをFA各ノードのためのボトムアップ処理を考慮し、又はいずれの場合にも満足できません。限り、私たちは各ノードの息子の最大値を見つけ、他の息子を更新して、更新の合計との違いが答えです。

詳細:
DISオープン長い長い注
DIS更新リーフノード対応する距離に子ノードが同じではないので、[]、この点の右側ではないだけが、[I] wが結合していると継続します

エラーコード

void  dfs( int u , int fa ){
    ll sum = 0LL , ma = 0LL , cnt = 0LL ;
    for( int i = head[ u ] ; i ; i = nex[ i ] ){
        if( to[ i ] == fa )continue ;
        dfs( to[ i ] , u ) ;
        sum += (ll)w[ i ] , ma = max( (ll)w[ i ] , ma ) , cnt++ ;
    }
    ans += ma*cnt - sum ;
}

正しい言葉遣い

void  dfs( int u , int fa ){
    ll sum = 0LL , ma = 0LL ;
    for( int i = head[ u ] ; i ; i = nex[ i ] ){
        if( to[ i ] == fa )continue ;
        dfs( to[ i ] , u ) ;
        ma = max( dis[ to[i] ] + w[ i ] , ma ) ;//统计最大值
    }
    dis[ u ] = ma ; //更新dis[ u ]
    for( int i = head[ u ] ; i ; i = nex[ i ] ){
        if( to[ i ] == fa )continue ;
        ans += dis[ u ] - w[ i ] - dis[ to[ i ] ] ;  //统计贡献
    }
}

完全なコード

#include<bits/stdc++.h>
using namespace std ;
#define ll long long
const int MAXN = 500005 ;
inline int read(){
    int s=0 ; char g=getchar() ; while(g>'9'||g<'0')g=getchar() ; 
    while(g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ;
}
int N , root , to[ MAXN*2 ] , nex[ MAXN*2 ] , head[ MAXN ] , w[ MAXN*2 ] , tot = 1;
ll ans = 0LL , dis[ MAXN ];
void add( int x , int y , int z){
    to[ ++tot ] = y , nex[ tot ] = head[ x ] , w[ tot ] = z , head[ x ] = tot ;
} 
void  dfs( int u , int fa ){
    ll sum = 0LL , ma = 0LL ;
    for( int i = head[ u ] ; i ; i = nex[ i ] ){
        if( to[ i ] == fa )continue ;
        dfs( to[ i ] , u ) ;
        ma = max( dis[ to[i] ] + w[ i ] , ma ) ;
    }
    dis[ u ] = ma ; 
    for( int i = head[ u ] ; i ; i = nex[ i ] ){
        if( to[ i ] == fa )continue ;
        ans += dis[ u ] - w[ i ] - dis[ to[ i ] ] ;  
    }
}
int main(){
    N = read() , root = read() ; int m1 , m2 , m3 ;
    for( int i = 1 ;  i < N ; ++i ){
        m1 = read() , m2 = read() , m3 = read() ;
        add( m1 , m2 , m3 ) , add( m2 , m1 , m3 ) ;
    }
    dfs( root , root ) ;
    cout<<ans ;
    return 0 ;
}

不十分な場合は、ギャングを明記してください

おすすめ

転載: www.cnblogs.com/ssw02/p/11431951.html
おすすめ