zoukankan      html  css  js  c++  java
  • 关于树的重心--POJ 1655

    树的重心的定义:

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

    通俗来说就是以这个点为根节点,找到他最大的衣蛾子树,然后让这个子树最小。

    例题加模板:

    POJ 1655

    #include<iostream>
    #include<vector>
    #include<cstring>
    using namespace std;
    const int N=2E4+7;
    vector<int >ve[N];
    bool mark[N];
    
    int ans=N,pos;
    int n;
    
    int dfs(int x){
        mark[x]=1;
        int sum=0;//sum为以x为根节点,其包含的点的总数目。
        int s=0;
        for(int i=0;i<ve[x].size();i++){
            if(mark[ve[x][i]]) continue ;
            int x1=dfs(ve[x][i]);
            s=max(s,x1);//
            sum+=x1;
        }
        s=max(s,n-sum-1);//以x为根节点,s是X下边的点集的最大值,n-sum-1是x点上边的点集的最大值
    //  ans=min(ans,s);//最大子树最小if(s<=ans){
            if(s==ans){
                pos=min(pos,x);
            }
            else {
                ans=s;
                pos=x;
            }
        }
        return sum+1;
    }
    void solve()
    {
        ans=N;
        memset(mark,0,sizeof mark);
        cin>>n;
        int x,y;
        for(int i=1;i<=n;i++) ve[i].clear();
        for(int i=1;i<=n-1;i++){
            cin>>x>>y;
            ve[x].push_back(y);
            ve[y].push_back(x);
        }
        dfs(1);
        cout<<pos<<" "<<ans<<endl;
    }
    int main(){
        ios::sync_with_stdio(0);
        int t;
        cin>>t;
        while(t--) solve();
        return 0;
    }

     树的重心的一些性质:

    1 树上所有的点到重心的距离和最小,可能会有两个重心,此时到这两个重心的距离和最小

    2 把两棵树通过一条边相连,新的树的重心在原来两棵树重心的连线上。
    3 一棵树添加或者删除一个节点,树的重心最多只移动一条边的位置。

    4 一棵树最多有两个重心,并且这两个重心相邻

  • 相关阅读:
    问题及解决:使用dotnet publish发布时Visual Stuido创建的配置文件中的路径失效
    模式的定义
    Identity Server 4 从入门到落地(三)—— 创建Web客户端
    信息系统的不能和能
    虚拟机中CentOS 6.8 Linux搭建GitLab服务器(安装篇)
    Eclipse快捷键大全
    冒泡排序实现
    JAVA的数据类型
    IDEA快捷键大全(翻译自官方手册)
    IntelliJ IDEA入门设置指南
  • 原文地址:https://www.cnblogs.com/Accepting/p/11848303.html
Copyright © 2011-2022 走看看