zoukankan      html  css  js  c++  java
  • bzoj2286: [Sdoi2011]消耗战

    思路:建出虚树然后treedp即可,f[i]表示将以i为根的子树与根隔绝的最小代价,f[i]=min(val[i],Σf[son[i]])(val[i]表示将点i与根隔绝的代价),需要注意的是如果i就是关键点那么f[i]=val[i]。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 250005
    #define inf (~0ull>>1)
    #define min(x,y) (x)>(y)?(y):(x)
     
    int n,tot,deg,m,top;
    int now[maxn],pre[maxn*2],son[maxn*2],val[maxn*2],dfn[maxn],dep[maxn];
    int a[maxn],stack[maxn];
    long long dp[maxn],minval[maxn];
    int f[maxn][21];
    bool vis[maxn];
     
    inline int read(){
        int x=0;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar());
        for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
        return x;
    }
     
    void add(int a,int b,int c){
        son[++tot]=b;
        pre[tot]=now[a];
        now[a]=tot;
        val[tot]=c;
    }
     
    void link(int a,int b,int c){
        add(a,b,c),add(b,a,c);
    }
     
    void dfs(int x,int fa){
        dep[x]=dep[fa]+1,dfn[x]=++deg;
        for (int p=now[x];p;p=pre[p])
            if (son[p]!=fa){
                f[son[p]][0]=x,minval[son[p]]=min(minval[x],val[p]);
                dfs(son[p],x);
            }
    }
     
    int lca(int a,int b){
        if (dep[a]<dep[b]) swap(a,b);int x=dep[a]-dep[b],t=0;
        for (;x;x>>=1,t++) if (x&1) a=f[a][t];
        if (a==b) return a;t=log2(dep[a])+1;
        for (;f[a][0]!=f[b][0];){
            for (;f[a][t]==f[b][t];) t--;
            a=f[a][t],b=f[b][t];
        }
        return f[a][0];
    }
     
    void tree_dp(int x){
        dp[x]=minval[x];long long sum=0;
        for (int p=now[x];p;p=pre[p]) tree_dp(son[p]),sum+=dp[son[p]];
        if (sum&&!vis[x]) dp[x]=min(dp[x],sum);now[x]=0;
    }
     
    bool cmp(int a,int b){return dfn[a]<dfn[b];}
     
    int main(){
        n=read();minval[1]=inf;
        for (int i=1,aa,b,c;i<n;i++) aa=read(),b=read(),c=read(),link(aa,b,c);
        dfs(1,0); memset(now,0,sizeof(now)),tot=0; m=read();
        for (int i=1;i<=20;i++)
            for (int x=1;x<=n;x++)
                f[x][i]=f[f[x][i-1]][i-1];
        while (m--){
            int len=read();top=0;
            for (int i=1;i<=len;i++) a[i]=read(),vis[a[i]]=1;
            sort(a+1,a+len+1,cmp);
            for (int i=1;i<=len;i++){
                if (!top){stack[++top]=a[i];continue;}
                int x=lca(stack[top],a[i]);
                for (;dfn[x]<dfn[stack[top]];){
                    if (dfn[x]>=dfn[stack[top-1]]){
                        add(x,stack[top],0);
                        if (stack[--top]!=x) stack[++top]=x;
                        break;
                    }
                    add(stack[top-1],stack[top],0),top--;
                }
                stack[++top]=a[i];
            }
            while (top>1) add(stack[top-1],stack[top],0),top--;
            tree_dp(stack[1]),printf("%lld
    ",dp[stack[1]]);
            for (int i=1;i<=len;i++) vis[a[i]]=0;tot=0;
        }
        return 0;
    }
    
  • 相关阅读:
    java执行cmd程序
    修改linux 默认ssh的22端口
    docker入门(一)
    关键字:心跳网络、oracle rac 网络异常宕机、packet reassembles failed 、UDP error 转载大佬的一篇文章
    记录数据库心跳网络异常,导致数据库宕机--推荐使用OSWBB监控主机
    python项目一键导入所有安装包
    weblogic 中间件利用bsu 漏洞补丁升级
    weblogic 控制台密码输入5次错误被锁 / 密码忘记 修改密码的方法
    oracle数据泵工作学习记录
    简单粗暴的给Linux系统配置本地yum 源
  • 原文地址:https://www.cnblogs.com/DUXT/p/5992393.html
Copyright © 2011-2022 走看看