树的直径、树的重心与树的点分治

 

转载自:树的直径、树的重心与树的点分治

 


 

树的直径

  1.定义:

    树的直径(Diameter)是指树上的最长简单路。

  2.求解思路:

    两遍搜索 (BFS or DFS)

    任选一点w为起点,对树进行搜索,找出离w最远的点u。

    以u为起点,再进行搜索,找出离u最远的点v。

    则u到v的路径长度即为树的直径。

 


 

树的重心

  1.定义:

    找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡。

  2.求解思路:

    定义son[ i ]:以节点 i 为根节点的子树节点的总个数;

    对于节点 i,定义 cnt[ i ]为其所有子树中最大的子树节点个数;

    令 x = max{ son[ j ] }+1( j 为节点 i 的所有儿子节点),y = n-son[ i ]-1;

    那么,cnt[ i ]=max{x,y}

    使cnt[ i ]最小的 i 便是此树的重心;

代码:

 1 //初始cnt=INF,k=0
 2 void Dfs(int u,int f,int &cnt,int &k)
 3 {
 4     son[u]=0;
 5     int temp=0;
 6     for(int i=head[u];~i;i=G[i].next)
 7     {
 8         int v=G[i].to;
 9         if(v == f)
10             continue;
11 
12         Dfs(v,u,cnt,k);
13 
14         son[u] += son[v]+1;
15         temp=max(temp,son[v]+1);//以u的儿子节点为根节点的子树的最大节点个数
16     }
17     temp=max(temp,n-son[u]-1);
18     if(temp < cnt)
19     {
20         k=0;
21         a[k++]=u;//存储此树的所有重心
22         cnt=temp;//存储最大子树的最小节点个数
23     }
24     else if(temp == cnt)
25         a[k++]=u;
26 }
View Code

相关习题:

posted @ 2019-03-14 21:11  HHHyacinth  阅读(163)  评论(0编辑  收藏  举报