其他分享
首页 > 其他分享> > 题解:树

题解:树

作者:互联网

Description:

题目描述

  图论中的树为一个无环的无向图。给定一棵树,每个节点有一盏指示灯和一个按钮。如果节点的按扭被按了,那么该节点的灯会从熄灭变为点亮(当按之前是熄灭的),或者从点亮到熄灭(当按之前是点亮的)。并且该节点的直接邻居也发生同样的变化。
  开始的时候,所有的指示灯都是熄灭的。请编程计算最少要按多少次按钮,才能让所有节点的指示灯变为点亮状态。

输入格式

  输入文件有多组数据。
  输入第一行包含一个整数n,表示树的节点数目。每个节点的编号从1到n。输入接下来的n – 1行,每一行包含两个整数x,y,表示节点x和y之间有一条无向边。
当输入n为0时,表示输入结束。

输出格式

  对于每组数据,输出最少要按多少次按钮,才能让所有节点的指示灯变为点亮状态。每一组数据独占一行。

样例:

样例输入:

3
1 2
1 3
0

样例输出:

1

数据范围与提示

  对于100%的数据,满足1<=n<=100。

基本思路:

  题目中很明确,是一棵树嘛,所以考虑树状DP。定义状态数组:

c[i][j],i表示第i个点,j表示状态,取值为1~3;

  其中,状态1表示自己按,然后自己亮了;状态2表示自己不按然后亮了(被儿子弄亮了);状态3表示自己不按,自己也没亮。
那么有状态转移方程:

c[i][1]=sigma(c[son][3]);
c[i][2]=sigma(min(c[son][1],c[son][2]));
c[i][3]=sigma(min(c[son][1],c[son][2]));

  要注意:对于2、3状态,要统计儿子状态1的个数,如果是奇数则直接加到2状态里去,偶数就是3。此外,还要统计儿子里abs(c[son][1]-c[son][2])的最小值,然后与所的总和一起加到刚才没被赋值的状态里;
  还有一个问题,就是对于叶子节点,他的2、3状态没有意义,所以,c[leaf][2]=INT_MAX,c[leaf][3]=0,这样在统计时就不会统计他的2状态;
  然后往上DP就好了。
  这次没有代码。。。
2021.5.31 现役

标签:状态,点亮,题解,son,指示灯,节点,输入
来源: https://www.cnblogs.com/Geek-Kay/p/14831774.html