对于一棵树而言,记录下包含此结点的最大num和不包含此节点的最大num,进行dp。
我发现自己每每写完一题,就再也不想多写一个字,以至于解题报告如同旧时的电报,惜字如金。
enum
{
SIZE = 500001,
};
struct Node
{
int p; // parent
int u; // used son
int v1; // ocupy itself
int v0; // does not contain itself
int state; // state, use or not use
};
Node Tree[SIZE];
int Case, N;
void proc ()
{
int i;
for ( i = N; i >= 2; i -- )
{
Tree[i].v1 ++;
int p = Tree[i].p;
Tree[p].v1 += Tree[i].v0;
int u = Tree[p].u;
if ( u == -1 )
{
Tree[p].v0 += Tree[i].v1;
Tree[p].u = i;
}
else
{
if ( Tree[u].v0 + Tree[i].v1 > Tree[i].v0 + Tree[u].v1 )
{
Tree[p].v0 += Tree[i].v1 - Tree[u].v1 + Tree[u].v0;
Tree[p].u = i;
}
else
Tree[p].v0 += Tree[i].v0;
}
}
printf ( "%d/n", Tree[1].v0 * 1000 );
Tree[1].state = 0;
int f = 0;
for ( i = 2; i <= N; i ++ )
{
int p = Tree[i].p, u = Tree[i].u;
if ( Tree[p].state == 1 )
{
Tree[i].state = 0;
}
else
{
if ( Tree[p].u == i )
Tree[i].state = 1;
else
Tree[i].state = 0;
}
if ( Tree[i].state == 0 )
continue;
if ( f ++ )
printf ( " " );
printf ( "%d", i );
}
printf ( "/n" );
}
void init ()
{
memset ( Tree, 0, sizeof ( Tree ) );
scanf ( "%d", &N );
int i, t;
Tree[1].p = Tree[1].u = -1;
for ( i = 2; i <= N; i ++ )
{
scanf ( "%d", &t );
Tree[i].p = t;
Tree[i].u = Tree[i].state = -1;
}
}
int main ()
{
//freopen ( "in.txt", "r", stdin );
scanf ( "%d", &Case );
int i;
for ( i = 0; i < Case; i ++ )
{
if ( i )
printf ( "/n" );
init ();
proc ();
}
return 0;
}