zoukankan      html  css  js  c++  java
  • 洛谷 P1395 会议(树的重心)

    传送门


    解题思路

      为什么要找树的重心呢?假设我们已经找到了树的重心,如果把开会地点从重心向右移走,那么对答案的贡献就是+左边的元素和-右边的元素和。而因为是树的重心,所以向右移走后左面的元素数量一定大于右面的元素数量,所以ans是比在重心的情况大的,所以最终我们选择重心。

    AC代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=50005;
    int n,cnt,rt,maxp[maxn],ans,p[maxn],size[maxn];
    struct node{
        int v,next;
    }e[maxn*2];
    void insert(int u,int v){
        cnt++;
        e[cnt].v=v; 
        e[cnt].next=p[u];
        p[u]=cnt;
    }
    void getrt(int u,int fa){
        size[u]=1;
        for(int i=p[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(v==fa) continue;
            getrt(v,u);
            size[u]+=size[v]; 
            maxp[u]=max(maxp[u],size[v]);
        }
        maxp[u]=max(maxp[u],n-size[u]);
        if(maxp[u]==maxp[rt]&&u<rt) rt=u;
        else if(maxp[u]<maxp[rt]) rt=u;
    }
    void dfs2(int u,int fa,int deep){
        ans+=deep;
        for(int i=p[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(v==fa) continue;
            dfs2(v,u,deep+1);
        }
    }
    int main()
    {
        memset(p,-1,sizeof(p));
        cin>>n;
        for(int i=1;i<n;i++){
            int u,v;
            cin>>u>>v;
            insert(u,v);
            insert(v,u);
        }
        maxp[0]=0x3f3f3f3f;
        getrt(1,-1);
        dfs2(rt,-1,0);
        cout<<rt<<" "<<ans;
        return 0;
    }
  • 相关阅读:
    COJ 1691:前缀和
    COJ 1692:模拟
    POJ 3415:后缀数组+单调栈优化
    python拓展知识
    git总结
    好的文章及博客收集
    python爬虫总结
    ajax与java后台交互
    Java多线程与并发库
    Django框架创建
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13659238.html
Copyright © 2011-2022 走看看