• BZOJ2286: [Sdoi2011]消耗战


    题解:首先构造虚数 然后树DP即可

    /**************************************************************
        Problem: 2286
        User: c20161007
        Language: C++
        Result: Accepted
        Time:10752 ms
        Memory:94812 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    const int MAXN=3e5+10;
    #define ll long long
    #define pii pair<int,int>
    using namespace std;
    const int inf=1e9+10;
    vector<pii>vec[MAXN];
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    int n;
    int f[MAXN][21];ll minn[MAXN][21];
    int dep[MAXN],cnt,p[MAXN];
    int st[MAXN];int tot;
    vector<int>vv;
    ll ans[MAXN];bool vis[MAXN];
    void dfs(int v,int pre,int deep){
        dep[v]=deep+1;p[v]=++cnt;f[v][0]=pre;
        for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i].first;
        if(u!=pre){
            minn[u][0]=vec[v][i].second;
            dfs(u,v,deep+1);
        }
        }
    }
    void dfs1(int v){
        for(int i=1;i<=20;i++)f[v][i]=f[f[v][i-1]][i-1],minn[v][i]=min(minn[v][i-1],minn[f[v][i-1]][i-1]);
        for(int i=0;i<vec[v].size();i++){
        if(vec[v][i].first!=f[v][0])dfs1(vec[v][i].first);
        }
    }
    int Lca(int u,int v){
        if(dep[u]<dep[v])swap(u,v);
        int tmp=dep[u]-dep[v];
        for(int i=0;i<=20;i++)if(tmp&(1<<i)){u=f[u][i];}
        if(u==v){return u;}
        for(int i=20;i>=0;i--){
        if(f[u][i]!=f[v][i]){
            v=f[v][i];u=f[u][i];
        }
        }
        return f[v][0];
    }
    void built(int x){
        vv.push_back(x);
        if(!tot){st[++tot]=x;return ;}
        int lca=Lca(x,st[tot]);
    //    cout<<x<<"====="<<st[tot]<<" "<<lca<<endl;
        while(tot>1&&dep[lca]<dep[st[tot-1]]){
        vec[st[tot-1]].push_back(make_pair(st[tot],0));
        vec[st[tot]].push_back(make_pair(st[tot-1],0));
        tot--;
        }
        if(dep[lca]<dep[st[tot]]){
        vv.push_back(lca);
        vec[st[tot]].push_back(make_pair(lca,0));
        vec[lca].push_back(make_pair(st[tot],0));
        tot--;
        //  st[++tot]=lca;
        }
        if(!tot||dep[lca]>dep[st[tot]])st[++tot]=lca;
        st[++tot]=x;
    }
    ll dist(int u,int v){
        if(v==0)return inf;
        ll res=inf;
        for(int i=20;i>=0;i--){
        if(dep[f[u][i]]>dep[v]){
            res=min(res,minn[u][i]);
            u=f[u][i];
        }
        }
        res=min(res,minn[u][0]);
        return res;
    }
    void slove(int v,int pre){
       // cout<<v<<" "<<pre<<endl;
        for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i].first;
        if(u!=pre){
            slove(u,v);
            if(vis[u])ans[v]+=dist(u,v);
            else ans[v]+=min(dist(u,v),ans[u]);
        }
        }
       // cout<<v<<" "<<ans[v]<<" ::::"<<endl;
    }
    bool cmp(int aa,int bb){return p[aa]<p[bb];}
    vector<int>V;
    int main(){
        n=read();int u,v,vul;
        for(int i=1;i<n;i++)u=read(),v=read(),vul=read(),vec[u].push_back(make_pair(v,vul)),vec[v].push_back(make_pair(u,vul));
        int q;q=read();int k,last;dfs(1,0,0);dfs1(1);
        for(int i=1;i<=n;i++)vec[i].clear();
        for(int i=1;i<=q;i++){
        k=read();tot=0;
    //  V.push_back(1);
        for(int j=1;j<=k;j++)u=read(),V.push_back(u),vis[u]=1;
        sort(V.begin(),V.end(),cmp);
        for(int j=0;j<V.size();j++)built(V[j]);
        while(tot>1){vec[st[tot]].push_back(make_pair(st[tot-1],0)),vec[st[tot-1]].push_back(make_pair(st[tot],0));tot--;}
        //vv.push_back()
        if(st[1]!=1){vec[1].push_back(make_pair(st[1],0));vec[st[1]].push_back(make_pair(1,0));}
    //  else last=1;
    //  cout<<last<<endl;
        slove(1,0);
        printf("%lld
    ",ans[1]);
        if(st[1]!=1)vec[1].clear(),ans[1]=0;
        for(int j=0;j<vv.size();j++)vec[vv[j]].clear(),ans[vv[j]]=0,vis[vv[j]]=0;
        V.clear();vv.clear();
        } 
        return 0;
    }
    

    2286: [Sdoi2011]消耗战

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 5381  Solved: 2041
    [Submit][Status][Discuss]

    Description

    在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
    侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。

    Input

    第一行一个整数n,代表岛屿数量。

    接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。

    第n+1行,一个整数m,代表敌方机器能使用的次数。

    接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。

    Output

    输出有m行,分别代表每次任务的最小代价。

     

    Sample Input

    10
    1 5 13
    1 9 6
    2 1 19
    2 4 8
    2 3 91
    5 6 8
    7 5 4
    7 8 31
    10 7 9
    3
    2 10 6
    4 5 7 8 3
    3 9 4 6

    Sample Output

    12
    32
    22

    HINT

     对于100%的数据,2<=n<=250000,m>=1,sigma(ki)<=500000,1<=ki<=n-1

  • 相关阅读:
    ServletContentLIstener接口演示ServletContext的启动和初始化
    Filter过滤非法字符
    显示Servlet API主要版本,次要版本以及服务器系统信息
    示例:Servlet显示当前系统时间(时间格式化)
    Servlet编写登录界面
    示例:Servlet读取文件内容并在页面打印输出
    HttpServletRequest接口实例化的使用
    Servlet小示例:jsp页面提交信息Servlet接收并打印输出
    Servlet中如何实现页面转发
    Servlet获取当前服务器的实际路径
  • 原文地址:https://www.cnblogs.com/wang9897/p/9426564.html
Copyright © 2020-2023  润新知