树的重心(dfs)

思路:

(1)对于每个节点,都可能是重心,都可能因为删除而符合条件;

(2)于是考虑枚举每个节点,对于每个节点,必须使得研究其分割后连通块的个数的时间复杂度为O(1),于是考虑预处理。

(3)注意到其为树形结构,考虑递归dfs(u)用于返回以u为根节点的树的内部节点个数,在深搜过程中,一方面可以直接获取各个子树连通块内部节点个数;在统计完子树节点之后;加上自己本身,再用n减之,就得到上方部分连通块内部节点个数,在该过程中取max就得到去掉该节点最大连通块内部节点个数,同时开全局变量,在每个节点中取最小,就得到目标值。

(4)考虑用邻接表存储树。

代码:                                                                                           

 

#include

using namespace std;

const int N = 1e5 + 10;

int e[N*2],ne[N*2],idx,h[N];
int st[N];
int n;
void add(int a,int b)
{
    e[idx] = b,ne[idx] = h[a],h[a] = idx ++; 
}

int ans = N;

int dfs(int u)//返回该节点及子节点的个数
{
    st[u] = 1;
    
    int sum = 1,res = 0;
    for(int i = h[u];i != -1;i = ne[i])
    {
        int j = e[i];
        if(st[j] == 0)
        {
            int s = dfs(j);
            sum += s;
            res = max(s,res);
        }
    }
    
    res = max(res,n - sum);
    
    ans = min(ans,res);
    
    return sum;
}

int main()
{

    cin >> n;
    
    memset(h,-1,sizeof h);
    
    for(int i = 0;i < n - 1;i ++)
    {
        int a,b;
        cin >> a >> b;
        add(a,b);
        add(b,a);
    }
    
    dfs(1);
    
    
    cout << ans << endl;
    
    return 0;
}

你可能感兴趣的:(深度优先,算法,数据结构)