zoukankan      html  css  js  c++  java
  • 2019icpc徐州站 M 【Kill the tree】(找各点重心)

    题目链接https://nanti.jisuanke.com/t/42552

    题意:一开始建1个以1为root的树,然后找以各个节点作为根其子树中的重心是谁

    解法:推荐博客:https://www.cnblogs.com/ctyakwf/p/12010370.html

       这个题是一个非常不错的重心性质问题。我们以son代表以x为根的重儿子。倘若siz[son]*2>=siz[x],那么这个重心势必在son的重心和x之间,否则就是x。所以呢我们需要在res[son]至x中间爬,爬到所谓真正的x的重心(我们一开始都初始化x的重心为他自己),一旦siz[x]-2*siz[res[son]]>0,那么代表这个x的真正重心还能往上爬。爬到<=为止。最后你需要特判一下if(siz[x]==2*siz[res[x]])。这种等于情况显然就是会出现2个重心的情况,会出现两个解。

    AC代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int tot,head[maxn];
    struct E{
        int to,next;
    }edge[maxn<<1];
    void add(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int fa[maxn],n;int siz[maxn],res[maxn],res1[maxn];
    void dfs(int x,int f){
        siz[x]=1;res[x]=x;
        int son=0;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==f) continue;
            fa[v]=x;
            dfs(v,x);
            siz[x]+=siz[v];
            if(siz[v]>siz[son]) son=v;
        }
        if(siz[son]*2>=siz[x]){
            res[x]=res[son];
            while(siz[x]-2*siz[res[x]]>0){
                res[x]=fa[res[x]];
            }
            if(siz[x]==2*siz[res[x]]){
                res1[x]=fa[res[x]];
            }
        }
    }
    int main(){
        scanf("%d",&n);mem(head,-1);
        rep(i,1,n-1){
            int u,v;scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        fa[1]=1;
        dfs(1,-1);
        rep(i,1,n){
            if(res1[i]) printf("%d ",min(res1[i],res[i]));
            printf("%d
    ",max(res1[i],res[i]));
        }
    }
    View Code
  • 相关阅读:
    c# 网络编程
    .net基础------抽象类和接口区别
    自己开发插件-------- 待续...........
    js 学习笔记 (this ,扩展方法,匿名函数)
    meta
    微信公众号支付接口-JSAPI
    跨境电商-311xml报文生成 更新到2018-10
    MooTools 异步请求验证
    微信JS-SDK 接口调用与 php 遇到的坑
    php 与 jquery中$.post()与attr()方法的简单实例 amaze modal 模态窗口
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13345446.html
Copyright © 2011-2022 走看看