• poj 1655 找树的重心


    树形DP 求树的重心,即选择一个结点删去,使得分出的 若干棵树的结点数 的最大值最小

    #include<map>
    #include<set>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define mod 998244353
    #define pi acos(-1)
    #define inf 0x7fffffff
    #define ll long long
    using namespace std;
    ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int T,n,ans;
    int size[20005],mx[20005];
    vector<int>e[20005];
    void dp(int x,int fa)
    {
        size[x]=1;
        for(int i=0;i<e[x].size();i++)
        {
            int y=e[x][i];
            if(y==fa)continue;
            dp(y,x);//先算离最远的点
            size[x]+=size[y];size(x)表示以x为根除去pre点的树的点的个数
            mx[x]=max(mx[x],size[y]);//根据题意要找的是子树里最大的
        }
        mx[x]=max(mx[x],n-size[x]);
        if(mx[x]<mx[ans])ans=x;
        if(mx[x]==mx[ans]&&x<ans)ans=x;
    }
    int main()
    {
        T=read();
        while(T--)
        {
            n=read();ans=0;
            mx[0]=inf;
            for(int i=1;i<n;i++)
            {
                int u=read(),v=read();
                e[u].push_back(v);
                e[v].push_back(u);
            }
            dp(1,0);
            printf("%d %d
    ",ans,mx[ans]);
            for(int i=1;i<=n;i++)e[i].clear();        
            memset(size,0,sizeof(size));
            memset(mx,0,sizeof(mx));
        }
        return 0;
    }
  • 相关阅读:
    如何启用EMGrid/Cloud Control的HTTP而非HTTPS协议登陆
    Oracle Enterprise Manager 12c 新特性:实时RealTime Addm
    php 面向对象三大特征
    C++ 运算符重载
    C++面向对象_复制构造函数+构造函数+析构函数+static+友元
    位运算符和位运算
    SqlHelper.class.php
    C++ 流
    C++ 虚函数与多态
    C++ 继承与派生
  • 原文地址:https://www.cnblogs.com/Aragaki/p/7343091.html
Copyright © 2020-2023  润新知