求树的重心 poj-3107

Godfather 求树的重心 poj-3107

题意:给一棵树,求出树的重心,树的重心为:删除该点之后,使得形成的多棵树中节点数最大值最小。

这题就是很简单了, 我可以用 \(sizes[u]\) 表示 节点u的子树大小, 那么如果删除节点u, 我没遍历u的儿子节点

\(sizes[son]\) 取一个最大值, 由于要删除u, 还好产生一棵树就是u的父亲节点, u的父亲节点的大小也就是

\(n - sizes[u]\) 也就是枚举找最大值,然后再最大值中找最小值。

ac代码:

#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;

const int N = 1e5;

int n;
int head[N];

struct edge{
    int to, nxt;
}e[2 * N];
int top = 1;

void add_edge(int u, int v){
    e[top].to = v;
    e[top].nxt = head[u];
    head[u] = top++;
}

int sizes[N];
int father[N];

void dfs(int u , int fa){
    sizes[u] = 1;
    father[u] = fa;
    for(int i = head[u]; i ; i = e[i].nxt){
        int to = e[i].to;
        if(to == fa)continue;
        dfs(to, u);
        sizes[u] += sizes[to];
    }
}


int main(){

    while(~scanf("%d", &n)){
        for(int i = 1; i <= n; i++){
           // g[i].clear();
            father[i] = 0;
            head[i] = 0;
        }
        for(int i = 1; i < n; i++){
            int u, v;
            scanf("%d %d", &u, &v);
            add_edge(u, v);
            add_edge(v, u);
        }
        dfs(1, 0);
        int minn = n + 1;
        for(int i = 1; i <= n; i++){
            int maxn = 0;
            for(int j = head[i]; j ; j = e[j].nxt){
                int to = e[j].to;
                if(to == father[i])continue;
                maxn = max(maxn, sizes[to]);
            }
            maxn = max(maxn, n - sizes[i]);
            minn = min(minn, maxn);
        }
        vector<int>v;
        for(int i = 1; i <= n; i++){
            int maxn = 0;
            if(n - sizes[i] == minn){
                v.push_back(i);
                continue;
            }
            for(int j = head[i]; j ; j = e[j].nxt){
                int to = e[j].to;
                if(to == father[i])continue; 
                maxn = max(maxn, sizes[to]);
                if(maxn == minn){
                    v.push_back(i);
                    break;
                }
            
            }
        }
        for(int i = 0; i < v.size(); i++){
            printf("%d ", v[i]);
        }
        puts("");
    }
posted @ 2020-06-27 11:58  ccsu_zhaobo  阅读(73)  评论(0编辑  收藏  举报