0
|
0__1__0
| | |
1__1__0
|
1
假设我有一个无向图。我们有以下条件:
只允许删除标记为“1”的节点。
删除任何节点都不能使图形成为林
允许删除多个节点,但必须满足上述条件。
计算通过上述过程可以生成的不同树(无树)的数量。注意这里没有“根”这个词。我们只计算不同的结构。
对于上述情况,答案是4,因为:
0
|
0 0
| |
1__1__0 ------> #1
|
1
0
|
0 0
| | -------> #2
1__1__0
0
|
0__1__0
| | ---------> #3
1 0
0
|
0__1__0 ---------> #4
|
0
我希望能得到任何帮助或提示。
(如果图已经是一棵树,在满足上述条件的前提下,我们仍然可以删除节点以获得新的树)
最佳答案
正如您已经指出的,一个简单的指数解决方案是获取1个节点的所有子集,并为每个子集检查移除节点是否获得一个树图。有两个想法可以帮助您剪除某些子集:
从最小到最大递增地构建1节点子集。如果您找到一个分区图,则不需要检查其任何超集。
我来表示示例a、b、c、d中的1节点:
0
|
0__A__0
| | |
C__B__0
|
D
删除
{A, B}
将对图形进行分区。因此,显然删除{A, B, C}
或{A, B, D}
或{A, B, C, D}
也会分割图形。您不需要显式地检查任何这些。(除非除一个分区图组件外,所有分区图组件仅由1个节点组成。然后删除所有这些单节点组件也可以获得有效的解决方案。您可能需要将此作为特例进行检查。)
一旦找到获得一棵树的单节点子集,那么只要图没有分区,再删除任何一个单节点也将获得一棵树。
例如,通过删除
A
可以得到一棵树:0
|
0 0
| |
C__B__0
|
D
我们可以通过移除更多的节点来生成更多的树。对于这些,我们只需要通过移除它们来检查,我们不会对图进行分区。如果不是,我们可以确定图仍然是一棵树。在这个例子中删除
D
说明了这个想法。在最坏的情况下,这些优化可能不会使算法优于指数算法,但它们可以使算法在合理的小输入下变得实用。