zoukankan      html  css  js  c++  java
  • bzoj3611: [Heoi2014]大工程

    题目链接

    bzoj3611: [Heoi2014]大工程

    题解

    虚树的构造就不讲了,详见我的上一篇博客
    bzoj 2286: [Sdoi2011]消耗战
    然后这题我们对于每条边计算全局贡献就好了
    最长、短链分别维护子树中,父节点再未更新时合并新答案就好了

    define int long long

    真好用 摔(╯‵□′)╯︵┻━┻

    代码

    #include<cstdio>
    #include<cstring> 
    #include<algorithm>
    #define INF 0x3f3f3f3f
    #define int long long 
    inline int read() { 
        int x = 0; 
        char c = getchar(); 
        while(c < '0' || c > '9')c = getchar(); 
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
        return  x; 
    } 
    const int maxn = 1000007; 
    struct node {
        int u,v,w,next;
    } edge[maxn << 1],e[maxn << 1] ;
    int head[maxn],h[maxn],deep[maxn],num,num1; 
    inline void add_edge(int u,int v) {
        edge[++ num].v = v;edge[num].next = head[u];head[u] = num; 
    } 
    inline void add(int u,int v) {if(u == v) return; e[++num1].v = v;e[num1].w = deep[v] - deep[u],e[num1].next = h[u];h[u] = num1; }  
    int n,dfn[maxn],dad[maxn][20],size[maxn],cnt = 0;   
    void dfs(int x) { 
        dfn[x] = ++cnt;
        deep[x] = deep[dad[x][0]] + 1; 
        for(int i = 0;dad[x][i];++ i) dad[x][i + 1] = dad[dad[x][i]][i]; 
            for(int i = head[x];i;i = edge[i].next) { 
            int v = edge[i].v; 
            if(v == dad[x][0]) continue; 
            dad[v][0] = x; 
            dfs(v); 
        }  
    }    
    int lca(int x,int y) {  
        if(deep[x] > deep[y])std::swap(x,y); 
        for(int i = 18;i >= 0;-- i) if(deep[dad[y][i]] >= deep[x]) y = dad[y][i]; 
        if(x == y) return x ; 
        for(int i = 18;i >= 0;-- i) if(dad[x][i] != dad[y][i]) x = dad[x][i],y = dad[y][i]; 
        return dad[x][0]; 
    } 
    inline bool cmp(int x,int y)  { return dfn[x] < dfn[y]; } 
    int stack[maxn]; 
    int v[maxn]; 
    int mn[maxn],mx[maxn];long long dp[maxn]; int ans1,ans2; 
    int k; 
    void Dp(int x) {
        int tmp = 0;
        size[x] = v[x]; dp[x] = 0;
        mn[x] = v[x] ? 0 : INF; 
        mx[x] = v[x] ? 0 : -INF;
        for(int i = h[x];i;i = e[i].next) {
            int v = e[i].v; 
            Dp(v); 
                dp[x] += dp[v] + 1ll * (size[v] * e[i].w * (k - size[v]));  
            size[x] += size[v]; 
            ans1 = std::min(ans1,mn[x] + mn[v] + e[i].w); 
            ans2 = std::max(ans2,mx[x] + mx[v] + e[i].w); 
            mn[x] = std::min(mn[v] + e[i].w,mn[x]); 
            mx[x] = std::max(mx[v] + e[i].w,mx[x]); 
        } 
        h[x] = 0; 
    } 
    int t[maxn];
    void solve(int top = 0) { 
        k = read(); 
        for(int i = 1;i <= k;++ i) t[i] = read(),v[t[i]] = 1;  
        std::sort(t + 1,t + k + 1,cmp); 
        //stack[++ top] = 1; 
        for(int i = 1;i <= k;++ i) { 
             if (!top){stack[++ top]=t[i];continue;}   
             int x = t[i],f = lca(stack[top],x); 
             if(f == stack[top]) {stack[++ top] = x; continue;} 
             while("tle") { 
                if(deep[f] >= deep[stack[top - 1]]) { 
                    add(f,stack[top --]);  
                    if(stack[top] != f) stack[++ top] = f; 
                    break; 
                } 
                add(stack[top - 1],stack[top]);top --; 
             }  
             if(stack[top] != x) stack[++ top] = x; 
        } 
        while(-- top) add(stack[top],stack[top + 1]); 
        ans1 = INF,ans2 = -INF ;  
        Dp(stack[1]);  
        printf("%lld %lld %lld
    ",dp[stack[1]],ans1,ans2);
        for(int  i = 1;i <= k;++ i) v[t[i]] =  0;
        return ;
    } 
     main() { 
        n = read();
        for(int u,v,i = 1;i < n;++ i) { 
            u = read(),v = read(); 
            add_edge(u,v);add_edge(v,u); 
        }   
        dfs(1); 
        int q = read();  
        for(int i = 1;i <= q;++ i) 
            solve(); 
        return 0; 
    } 
    
  • 相关阅读:
    获得微软最具影响力开发者(GDI)
    推荐一个制作卡通头像的网站(超强)
    李煜词全集
    15款语言学习2.0网络服务
    SNS社么时候回归社交? !!
    公司附近雪景
    Powershell实践之Discuz!NT自动打包发布
    使用 Office Live 时 Install Office Live Update 1.2出错的解决办法
    修改linux swap空间的swappiness,降低对硬盘的缓存
    TFS "TF30063: 您没有权限访问 MicrosoftIIS/7.0."
  • 原文地址:https://www.cnblogs.com/sssy/p/9128193.html
Copyright © 2011-2022 走看看