p2315_树形规划.cpp

来自「高手写的所有acm例程 在acm.zju.edu.cn 上的题目的例程」· C++ 代码 · 共 72 行

CPP
72
字号
#include <stdio.h>
#include <string.h>

#define  MAXN     500001

bool     Get [MAXN];
int      N , LeftChild [MAXN] , RightBrother [MAXN] , Give [MAXN] , Opt [2] [MAXN];

void     init ();
void     Cal ( int );
void     DTime_ ( int , int );
void     Print ();

main ()
{
     int total;
     for ( scanf ( "%d" , &total ); total; total -- ) {
         init ();
         Cal ( 1 );
         DTime_ ( 1 , 0 );
         Print ();
         if ( total > 1 ) puts ( "" );
     }
}

void Print ()
{
     bool  first = true;
     printf ( "%d000\n" , Opt [0] [1] );
     for ( int i = 1; i <= N; i ++ ) if ( Get [i] ) {
         if ( first ) first = false; else printf ( " " );
         printf ( "%d" , i );
     }
     printf ( "\n" );
}

void DTime_ ( int k , int state )
{
     if ( state ) Get [k] = true;
     for ( int i = LeftChild [k]; i; i = RightBrother [i] )
         DTime_ ( i , i == Give [k] );
}

void Cal ( int k )
{
     int Sum = 0 , Max = 0 , Choose = 0;
     for ( int i = LeftChild [k]; i; i = RightBrother [i] ) {
         Cal ( i );
         Sum += Opt [0] [i];
         if ( Opt [1] [i] - Opt [0] [i] > Max ) Max = Opt [1] [i] - Opt [0] [i] , Choose = i;
     }
     Opt [1] [k] = Sum + 1;
     Opt [0] [k] = Sum + Max;
     Give [k] = Choose;
}

void init ()
{
     scanf ( "%d" , &N );
     int Boss;
     
     memset ( Get , 0 , sizeof ( Get ));
     memset ( LeftChild , 0 , sizeof ( LeftChild ));
     memset ( RightBrother , 0 , sizeof ( RightBrother ));
     memset ( Opt , 0 , sizeof ( Opt ));
     
     for ( int i = 2; i <= N; i ++ ) {
         scanf ( "%d" , &Boss );
         RightBrother [i] = LeftChild [Boss] , LeftChild [Boss] = i;
     }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?