• P4103 [HEOI2014]大工程


    题目

    P4103 [HEOI2014]大工程
    化简题目:在树上选定(k)个点,求两两路径和,最大的一组路径,最小的一组路径

    做法

    关键点不多,建个虚树跑一边就好了
    (sum_i)(i)子树各关键点到根节点的距离和,(small_i)为其最小值,(big_i)为其最大值

    My complete code

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long LL;
    inline LL Read(){
        LL x(0),f(1); char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1; c=getchar();
        }
        while(c>='0'&&c<='9')
            x=(x<<3)+(x<<1)+c-'0',c=getchar();
        return x*f;
    }
    const LL maxn=2*1e6+9,inf=0x3f3f3f3f;
    LL n,ans1,ans2,ans3;
    LL a[maxn],sta[maxn];
    struct Tree{
        LL tot,num,head[maxn],dfn[maxn],dep[maxn],size[maxn],key[maxn],inc[maxn][25],fa[maxn];
        LL sum[maxn],big[maxn],small[maxn];
        struct node{
            LL to,next,d;
        }dis[maxn];
        inline void Add(LL u,LL v,LL d){
            dis[++num]=(node){v,head[u],d},head[u]=num;
        }
        void Fdfs(LL u){
            dfn[u]=++tot;
            inc[u][0]=fa[u];
            for(LL i=1;i<=21;++i)
                inc[u][i]=inc[inc[u][i-1]][i-1];
            for(LL i=head[u];i;i=dis[i].next){
                LL v(dis[i].to);
                if(v==fa[u])
                    continue;
                fa[v]=u,dep[v]=dep[u]+1,
                Fdfs(v);
            }
        }
        inline LL Lca(LL x,LL y){
            if(dep[x]<dep[y])
                swap(x,y);
            for(LL i=20;i>=0;--i)
                if(dep[inc[x][i]]>=dep[y])
                    x=inc[x][i];
            if(x==y)
                return x;
            for(LL i=20;i>=0;--i)
                if(inc[x][i]!=inc[y][i])
                    x=inc[x][i],y=inc[y][i];
            return inc[x][0];
        }
        void Dfs(LL u){
            size[u]=key[u],
            sum[u]=big[u]=0,
            small[u]=(key[u]==0)?inf:0;
            for(LL i=head[u];i;i=dis[i].next){
                LL v(dis[i].to),d(dis[i].d);
                Dfs(v);
                if(size[u]){
                    ans1+=size[u]*size[v]*d+size[u]*sum[v]+size[v]*sum[u],
                    ans2=min(ans2,small[u]+d+small[v]),
                    ans3=max(ans3,big[u]+d+big[v]);
                }
                sum[u]+=sum[v]+size[v]*d;
                small[u]=min(small[u],small[v]+d),
                big[u]=max(big[u],big[v]+d),
                size[u]+=size[v];
            }
            head[u]=key[u]=0;
        }
    }T,X;
    inline bool cmp1(LL x,LL y){
        return T.dfn[x]<T.dfn[y];
    }
    inline void Solve(){
        LL kase=Read();
        while(kase--){
            LL num(Read());
            for(LL i=1;i<=num;++i)
                a[i]=Read();
            sort(a+1,a+1+num,cmp1);
            LL tp; sta[tp=1]=1;
            for(LL i=1;i<=num;++i){
                X.key[a[i]]=1;
                LL lca=T.Lca(a[i],sta[tp]);
                while(T.dep[sta[tp]]>T.dep[lca])
                    if(T.dep[sta[tp-1]]<T.dep[lca])
                        X.Add(lca,sta[tp],T.dep[sta[tp]]-T.dep[lca]),sta[tp]=lca;
                    else
                        X.Add(sta[tp-1],sta[tp],T.dep[sta[tp]]-T.dep[sta[tp-1]]),--tp;
                if(sta[tp]!=a[i])
                    sta[++tp]=a[i];
            }
            while(tp>1)
                X.Add(sta[tp-1],sta[tp],T.dep[sta[tp]]-T.dep[sta[tp-1]]),--tp;
            ans1=0,ans2=inf,ans3=0;
            X.Dfs(1);
            printf("%lld %lld %lld
    ",ans1,ans2,ans3);
        }
    }
    int main(){
        n=Read();
        for(LL i=1;i<n;++i){
            LL u(Read()),v(Read());
            T.Add(u,v,1),T.Add(v,u,1);
        }
        T.Fdfs(1);
        Solve();
        return 0;
    }/*
    */
    
  • 相关阅读:
    label语句
    node.js入门(五)认识express和express-static中间件文件静态管理
    node.js(四)小结
    node.js入门(三)http数据解析
    node.js入门(二)文件系统
    node.js入门(一)搭建一个简单的服务
    微信小程序input安卓获取不了全英文的值
    微信小程序爬坑---textarea使用wx:if、wx:else、hidden的问题
    mysql补集合计算
    在Tomcat中配置基于springside的项目
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10287197.html
Copyright © 2020-2023  润新知