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

    定义:

    1.找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心。
    2.以这个点为根,那么所有的子树(不算整个树自身)的大小都不超过整个树大小的一半。

    性质:

    1.树中所有点到某一点距离之和中,到重心的距离和最短。

    2.把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上。
    3.把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离。

    DP的记忆化搜索来求解。

    const int maxn=500005;
    int tot=0,n;
    int ans,size;
    int sx[maxn],head[maxn];
    int vis[maxn];
    struct edge
    {
        int to,next;
    } eg[maxn];
    void add(int u,int v)
    {
        eg[tot].to=v;
        eg[tot].next=head[u];
        head[u]=tot++;
    }
    void init()
    {
        tot=0;
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
    }
    void dfs(int u)
    {
        vis[u]=1;
        sx[u]=1;
        int tmp=0;
        for(int i=head[u]; i!=-1; i=eg[i].next)
        {
            int v=eg[i].to;
            if(!vis[v])
            {
                dfs(v);
                sx[u]+=sx[v];
                tmp=max(tmp,sx[v]);
            }
        }
        tmp=max(tmp,n-sx[u]);
        if(size>tmp||size==tmp&&ans>u)
        {
            ans=u;
            size=tmp;
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            init();
            int u,v;
            scanf("%d",&n);
            for(int i=1; i<n; i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
            }
            size=INF;
            dfs(1);
            printf("%d %d
    ",ans,size);
        }
    }
    
  • 相关阅读:
    Windows10 iis10 arr webfarm
    两个command的疑惑
    关于controller和apicontroller的跨域实现过滤器的不同
    抽象工厂
    c# 字体库跨域解决
    c# 父类的引用指向子类的实例
    垂直居中
    扇形导航
    2D变换
    京东放大镜效果
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798755.html
Copyright © 2011-2022 走看看