zoukankan      html  css  js  c++  java
  • poj3107(树的重心,树形dp)

    题目链接:https://vjudge.net/problem/POJ-3107

    题意:求树的可能的重心,升序输出。

    思路:因为学树形dp之前学过点分治了,而点分治的前提是求树的重心,所以这题就简单水了一下。用sz[u]记录子树u的大小,son[u]记录以u为根时,子结点中最大的结点数。所以:

        son[u]=max(son[v],n-sz[u]),前一部分son[v]好理解,对于n-sz[u],即结点u的父结点那一块的大小。

    AC code:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn=50005;
    int n,cnt,head[maxn],sz[maxn],son[maxn];
    
    struct node1{
        int v,nex; 
    }edge[maxn<<1];
    
    struct node2{
        int val,id;
    }ans[maxn];
    
    void adde(int u,int v){
        edge[++cnt].v=v;
        edge[cnt].nex=head[u];
        head[u]=cnt;
    }
    
    bool cmp(node2 a,node2 b){
        if(a.val==b.val) return a.id<b.id;
        return a.val<b.val;
    }
    
    void getroot(int u,int fa){
        sz[u]=1,son[u]=0;
        for(int i=head[u];i;i=edge[i].nex){
            int v=edge[i].v;
            if(v==fa) continue;
            getroot(v,u);
            sz[u]+=sz[v];
            son[u]=max(son[u],sz[v]);
        }
        son[u]=max(son[u],n-sz[u]);
        ans[u].val=son[u],ans[u].id=u;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<n;++i){
            int u,v;
            scanf("%d%d",&u,&v);
            adde(u,v);
            adde(v,u);
        }
        getroot(1,0);
        sort(ans+1,ans+n+1,cmp);
        printf("%d",ans[1].id);
        for(int i=2;i<=n&&ans[i].val==ans[1].val;++i)
            printf(" %d",ans[i].id);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    第三方类AFNetworking(一)
    objective-C nil,Nil,NULL 和NSNull的小结
    DOM解析XML文件
    设置导航栏字体大小,颜色和加粗字体的方法
    数据本地化之沙盒机制
    本地存储Sqlite的用法:
    iOS面试题
    iOS 知识-常用小技巧大杂烩
    怎么升级iOS10教程
    2016WWDC详解
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11469192.html
Copyright © 2011-2022 走看看