Skip to content

Latest commit

 

History

History

1617.Count-Subtrees-With-Max-Distance-Between-Cities

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

1617.Count-Subtrees-With-Max-Distance-Between-Cities

本题要求统计:对于每一种长度d,有多少个subtree的最大直径等于d。根据长度来“构造”满足条件的树,其实是比较困难的。我们可以反过来想,对于每个subtree,我们查看它的最大直径是多少,然后做统计的aggregation。根据一个固定的subtree,求最大直径,这是一个确定性的问题,通常比构造性的问题简单的多。另外这个题目中节点数目小于等于15,穷举所有subtree(包括非法的不连通的图),也就是2^15=32768种,这是可以接受的。

给定了一棵树的拓扑结构,如何计算它的最长直径呢?这是一个经典的问题,有着经典的o(N)的解法:(参见 LC 1245.Tree-Diameter)

  1. 以图里的任意一个节点作为起始点A(看做根),往外做BFS遍历,能够到达的最远的节点B,那么B一定是最大直径的一个端点。
  2. 我们以B作为起始点(看做根),往外做BFS遍历,能够到达的最远的节点C,那么BC的路径就是最大直径的距离。

我们来给第一步的这个结论做个证明。第二步其实就是再次利用了这个结论。

假设从任意点A开始,能够到达的最远的距离是B。另外,整张图里“最长的点到点距离”是S和T。我们要证明B只可能是S或者T中的一点。如果不是,那么分情况讨论:

(1) AB与ST完全不相交。

 A --X-- B
     |
 S --Y-- T

那么我们从A找一条能够到达ST的路径,并令分叉点是X和Y。因为AB是从A起始的最长路径,那么AB>AX+XY+XT,即BX>XY+YT.

那么我们观察路径S->Y->X->B,其距离SY+YX+XB > SY+2XY+YT = ST+2XY > ST,这就与ST是全局“最长的点到点距离”矛盾。

(2) AB与ST相交于X。

     A 
     |
 S ==X== T
     |
     B

因为AB是从A起始的最长路径,那么AX+XB>AX+XS,即XB>XS.

我们观察路径B->X->T,其距离BX+XT > XS+XT = ST,这就与ST是全局“最长的点到点距离”矛盾。

(3) 还有一些corner cases,都容易结合图形分析。

由此我们证明了,只要用两次BFS找到两个“最远距离”,就可以确定一棵树的最大直径。

本题的基本思路就是:

  1. 枚举节点的组合尝试构成一棵树
  2. 如果这棵树是联通的,那么就求它的最长直径。
  3. 对于该直径的subtree统计就加1。

如何快速判断树是联通的呢?很简单,在BFS的时候判断是否经过了所有这个树的节点就行了。