zoukankan      html  css  js  c++  java
  • 树的重心及其性质

    性质:

      1.删除重心后所得的所有子树,节点数不超过原树的1/2,一棵树最多有两个重心;

      2.树中所有节点到重心的距离之和最小,如果有两个重心,那么他们距离之和相等;

      3.两个树通过一条边合并,新的重心在原树两个重心的路径上;

      4.树删除或添加一个叶子节点,重心最多只移动一条边;

           5.一棵树最多有两个重心,且相邻。

    证明:https://www.cnblogs.com/suxxsfe/p/13543253.htm  

    附一个求树的重心的板子题:Codeforces Round #670 (Div. 2)  C. Link Cut Centroids

    #include<bits/stdc++.h>
    #define rep(i, n) for(int i=0;i!=n;++i)
    #define per(i, n) for(int i=n-1;i>=0;--i)
    #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
    #define rep1(i, n) for(int i=1;i<=n;++i)
    #define per1(i, n) for(int i=n;i>=1;--i)
    #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
    #define L rt<<1
    #define R rt<<1|1
    #define inf (0x3f3f3f3f)
    #define llinf (1e18)
    #define ALL(A) A.begin(),A.end()
    #define SIZE(A) ((int)A.size())
    #define MOD (1e9 + 7)
    #define PII pair<int,int>
    typedef long long i64;
    using namespace std;
    const int maxn = 1e5 + 32;
    vector<int> e[maxn];
    int sz[maxn];
    int rt,frt,n,x,p;//i节点连接的节点个数(除选定的根节点外)
    void dfs(int cur,int fa)
    {
        int mx = 0;//子节点最大的连接节点数
        sz[cur] = 1;//因为连接了父节点
        for(auto node: e[cur])
            if(node != fa){
                dfs(node,cur);
                sz[cur] += sz[node];
                mx = max(mx,sz[node]);
            }
        if(sz[cur]*2>=n && mx*2 < n) // sz[cur]*2<=n 则每一个子树必 <=n/2,可知为重心,mx*2 < n确保为最深层的重心
            rt = cur,frt = fa;       
    }
    void solve()
    {
        int x,y;  cin >> n;
        for(int i=1;i<=n;++i)
            e[i].resize(0);
        rep(i, n-1){
            cin >> x >> y;
            e[x].push_back(y);
            e[y].push_back(x);
        }
        
        dfs(1, 0);
        if(rt == 1){
            cout << "1 " << e[1][0] << endl;
            cout << "1 " << e[1][0] << endl;
        }else{
            if(e[frt].size() == 1)
                p = rt,x = frt;
            else{
                for(auto node: e[frt])
                    if(node != rt){
                        p = frt,x = node;
                        break;
                    }
            }
            cout << p << " " << x << endl;;
            cout << rt << " " << x << endl;
        }
    }
    int main() {
        ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
        int t;  cin >> t;
        while(t--)
            solve();
        return 0;
    }
    

      

  • 相关阅读:
    Oracel System.Data.OracleClient requires Oracle client software version 8.1.7 or greater错误的解决方法
    oracle中CASE 的用法(摘录)
    ajaxpro 的一些用法,是在vs.net2003上
    我所知道的web下的打印方法
    电容触摸技术实用教程
    BLE资料应用笔记 持续更新
    蓝牙BLE实用教程
    README
    android 应用笔记
    Git 教程
  • 原文地址:https://www.cnblogs.com/newstartCY/p/13663101.html
Copyright © 2011-2022 走看看