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

    传送门

    虚树裸题,建完虚树上tree dp就好了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=2.5e5+10;
    int f[maxn][20],nid,dep[maxn],top,st[maxn],n,m,id[maxn],q[maxn];
    struct oo{int cnt,pre[maxn*2],nxt[maxn*2],h[maxn],v[maxn*2];}a,b;
    long long w[maxn],ans[maxn];
    void add(int x,int y,int z)
    {
        a.pre[++a.cnt]=y,a.nxt[a.cnt]=a.h[x],a.h[x]=a.cnt,a.v[a.cnt]=z;
        a.pre[++a.cnt]=x,a.nxt[a.cnt]=a.h[y],a.h[y]=a.cnt,a.v[a.cnt]=z;
    }
    void dfs(int x,int fa)
    {
        for(rg int i=1;i<20;i++)
        {
            if((1<<i)>dep[x])break;
            f[x][i]=f[f[x][i-1]][i-1];
        }
        id[x]=++nid;
        for(rg int i=a.h[x];i;i=a.nxt[i])
            if(a.pre[i]!=fa)
            {
                f[a.pre[i]][0]=x,dep[a.pre[i]]=dep[x]+1;
                w[a.pre[i]]=min(w[x],1ll*a.v[i]),dfs(a.pre[i],x);
            }
    }
    int lca(int x,int y)
    {
        if(dep[x]>dep[y])swap(x,y);
        int poor=dep[y]-dep[x];
        for(rg int i=19;i>=0;i--)if(poor&(1<<i))y=f[y][i];
        for(rg int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
        return x==y?x:f[x][0];
    }
    bool cmp(int x,int y){return id[x]<id[y];}
    void link(int x,int y)
    {
        b.pre[++b.cnt]=y,b.nxt[b.cnt]=b.h[x],b.h[x]=b.cnt;
        b.pre[++b.cnt]=x,b.nxt[b.cnt]=b.h[y],b.h[y]=b.cnt;
    }
    void dp(int x,int fa)
    {
        long long now=0;ans[x]=w[x];
        for(rg int i=b.h[x];i;i=b.nxt[i])if(b.pre[i]!=fa)dp(b.pre[i],x),now+=ans[b.pre[i]];
        b.h[x]=0;
        if(now)ans[x]=min(ans[x],now);
    //	printf("%d %d %d
    ",x,ans[x],w[x]);
    }
    signed main()
    {
        read(n);
        for(rg int i=1,x,y,z;i<n;i++)read(x),read(y),read(z),add(x,y,z);
        w[1]=1e17,dfs(1,0),read(m);
        for(rg int x=1,t;x<=m;x++)
        {
            read(t),b.cnt=top=0;
            for(rg int i=1;i<=t;i++)read(q[i]);
            sort(q+1,q+t+1,cmp);st[++top]=1;int tot=1;
            for(rg int i=2;i<=t;i++)if(lca(q[i],q[tot])!=q[tot])q[++tot]=q[i];
            for(rg int i=1;i<=tot;i++)
            {
                int w=0,e=0;
                while(top&&lca(st[top],q[i])!=st[top])
                {
                    if(w)link(w,st[top]);
                    w=st[top],top--;
                }
                if(w)e=lca(w,q[i]),link(w,e);
                if(e&&e!=st[top])st[++top]=e;
                st[++top]=q[i];
            }
            while(top>1)link(st[top],st[top-1]),top--;
            dp(1,0);
            printf("%lld
    ",ans[1]);
        }
    }
    
  • 相关阅读:
    C++中整型变量的存储大小和范围
    A1038 Recover the Smallest Number (30 分)
    A1067 Sort with Swap(0, i) (25 分)
    A1037 Magic Coupon (25 分)
    A1033 To Fill or Not to Fill (25 分)
    A1070 Mooncake (25 分)
    js 获取控件
    C#代码对SQL数据库添加表或者视图
    JS 动态操作表格
    jQuery取得下拉框选择的文本与值
  • 原文地址:https://www.cnblogs.com/lcxer/p/10369454.html
Copyright © 2011-2022 走看看