627 F.最大ホワイトサブツリーツリーCF [DP]

 

 

 

 

 

 

 

 

 

思考

  右、最大点を見つけるために右の部分木に少し黒と白の1ビットので-1権利。

  セットF [I]はI重量ポイントを含むサブツリーの最高点である場合の最大点と現在の点の重量   比  と最大電流点右点父親の小さなは、現在のポイントが更新されます。

  比較愚かなアプローチは、右と現在のポイントは、0未満またはプロセスが異なる点である場合よりも大きい、次の2つの場合に議論されています。

  もし現在のアイデアツリーの重み> = 0、そして父の右部分木の大きい値、すべきサブツリーの現在位置に父親サブツリーのマージポイント。

  黒よりも現在のツリーのアイデアの重み<0、と父のサブツリーより白い場合は、現在のポイントと合併サブツリーの父ツリーにポイントを置きます。

 

コード

 

#include   < ビット/ STDC ++。H >
#define   DBG X  COUT  <<  #X  <<   " = "   <<  X  <<  ENDL
#define   EPS   1E - 8
#define   パイ  ACOS - 1.0

using  namespace  std ;
typedef  long  long LL ;

const  int inf  =  0x3f3f3f3f ;

template < class  T > inline  void  read ( T  & res )
{
     char c ;T flag = 1 ;
     while ((c = getchar ()) < ' 0 ' ||c > ' 9 ' ) if (c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
     while ((c = getchar ()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}

namespace  _buff  {
     const  size_t BUFF  =  1  <<  19 ;
     char  ibuf [BUFF ],  *ib  = ibuf ,  *ie  = ibuf ;
     char  getc ()  {
         if  (ib  == ie )  {
            ib  = ibuf ;
            ie  = ibuf  +  fread (ibuf ,  1 , BUFF , stdin );
         }
         return ib  == ie  ?  - 1  :  *ib ++ ;
     }
}

int  qread ()  {
     using  namespace  _buff ;
     int ret  =  0 ;
     bool pos  =  true ;
     char c  =  getc ();
     for  (;  (<  ' 0 '  || c  >  ' 9 ' )  && c  !=  ' - ' ; c  =  getc ())  {
         assert ( ~c );
     }
     if  (==  ' - ' )  {
        pos  =  false ;
        c  =  getc ();
     }
     for  (; c  >=  ' 0 '  && c  <=  ' 9 ' ; c  =  getc ())  {
        ret  =  (ret  <<  3 )  +  (ret  <<  1 )  +  (^  48 );
     }
     return pos  ? ret  :  -ret ;
}

const  int maxn  =  2e5  +  7 ;

int a [maxn ];
int n ;
int head [maxn  <<  1 ], edge [maxn  <<  1 ], nxt [maxn  <<  1 ], cnt ;
int f [maxn ];
bool vis [maxn ];
int ans [maxn ];

void  BuildGraph ( int  u ,  int  v )  {
    cnt ++ ;
    edge [cnt ]  = v ;
    nxt [cnt ]  = head [u ];
    head [u ]  = cnt ;
}

void  dfs ( int  u ,  int  fa )  {
     if (a [u ]  ==  1 )  {
         f [u ]  =  1 ;
     }
     else  {
         f [u ]  =  - 1 ;
     }
    //printf("f[%d]:%d\n",u, f[u]);
     for  (  int i  = head [u ]; i ; i  = nxt [i ]  )  {
         int v  =  edge [i ];
         if (== fa )
             continue ;
         else  {
             dfs (v , u );
             if ( f [v ]  >  0 )  {
                 f [u ]  +=  f [v ];
                //printf("f[%d]:%d\n",u, f[u]);
             }
         } 
     }
}

void  dp ( int  u ,  int  fa )  {
     if (f [u ]  >=  0 )  {
         int temp  =  f [fa ]  -  f [u ];
         if (temp  >=  0 )  {
             f [u ]  += temp ;
            //printf("f[%d]:%d\n",u, f[u]);
         }
     }
     else  {
        //printf("fa: f[%d]:%d\n",fa, f[fa]);
         if ( f [fa ]  >=  0 )  {
             f [u ]  +=  f [fa ];
            //printf("f[%d]:%d\n",u, f[u]);
         }
     }
     for  (  int i  = head [u ]; i ; i  = nxt [i ]  )  {
         int v  =  edge [i ];
        //dbg(v);
         if (== fa )
             continue ;
         else  {
             dp (v , u );
         }
     }
}

int  main ()
{
     read (n );
     for  (  int i  =  1 ; i  <= n ;  ++)  {
         read ( a [i ]);
     }
     for  (  int i  =  1 ; i  < n ;  ++)  {
         int u , v ;
         read (u );
         read (v );
         BuildGraph (u , v );
         BuildGraph (v , u );
     }
     dfs ( 1 ,  1 );
     dp ( 1 ,  1 );
     for  (  int i  =  1 ; i  <= n ;  ++)  {
         printf ( "%d   " , f [i ]);
     }
     return  0 ;
}

おすすめ

転載: www.cnblogs.com/orangeko/p/12483780.html