zoukankan      html  css  js  c++  java
  • 求树的重心

    给定一棵树,求树的重心的编号以及重心删除后得到的最大子树的节点个数size,如果size相同就选取编号最小的.

    首先要知道什么是树的重心,树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重

    心后,生成的多棵树尽可能平衡.  实际上树的重心在树的点分治中有重要的作用, 可以避免N^2的极端复杂度(从退化链的一端出发)

    算法就是跑一遍dfs,找到最优解。

    链接

    代码:

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    using namespace std;
    const int N = 20005;
    const int INF = 1<<30;
    int head[N];
    int son[N];
    bool vis[N];
    int cnt,n;
    int ans,size;
    struct Edge
    {
        int to;
        int next;
    };
    Edge edge[2*N];
    void Init()
    {
        cnt = 0;
        size = INF;
        memset(vis,0,sizeof(vis));
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v)
    {
        edge[cnt].to = v;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    void dfs(int cur)
    {
        vis[cur] = 1;
        son[cur] = 0;
        int tmp = 0;
        for(int i=head[cur]; ~i; i=edge[i].next)
        {
            int u = edge[i].to;
            cout<<u<<endl;
            if(!vis[u])
            {
                dfs(u);
                son[cur] += son[u] + 1;
                tmp = max(tmp,son[u] + 1);
            }
        }
        tmp = max(tmp,n-son[cur]-1);
        if(tmp < size || tmp == size && cur < ans)
        {
            ans = cur;
            size = tmp;
        }
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            Init();
            scanf("%d",&n);
            for(int i=1; i<=n-1; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            dfs(1);
            printf("%d %d
    ",ans,size);
        }
        return 0;
    }
  • 相关阅读:
    10/11
    el表达式的坑
    在idea下两个项目之间的maven父子级项目依赖
    树上任意两点间距离
    优先级顺序
    HDU 6447
    KMP
    cf 1029 C
    牛客练习赛25
    莫比乌斯算法
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9457881.html
Copyright © 2011-2022 走看看