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

    2286: [Sdoi2011消耗战

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 2082  Solved: 736
    [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

    Source

    Stage2 day2


    虚树入门题,如果你想知道虚树如何构造:http://user.qzone.qq.com/872191552/main

    DP

    记dis[i]为点i到根节点的路径中最小的边的权值

    f[i]=min(dis[i],sigma f[son[i]]);


      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<vector>
      8 #include<stack>
      9 #define maxn 500100
     10 #define llg long long
     11 using namespace std;
     12 struct node
     13 {
     14     llg df,po;
     15 }d[maxn];
     16 llg i,j,k,n,m,p[maxn][22],dad[maxn],bj[maxn],dfs[maxn],cnt,T,deep[maxn],dis[maxn],se[maxn],q,ss[maxn],open,dl[maxn];
     17 vector <llg> a[maxn],c[maxn],val[maxn];
     18 stack <llg> z;
     19 
     20 
     21 inline int getint(){
     22     char c=getchar(); llg w=0,q=0;
     23     while(c!='-' && ( c<'0' || c>'9')) c=getchar();
     24     if(c=='-') c=getchar(),q=1;
     25     while(c>='0' && c<='9') w=w*10+c-'0',c=getchar();
     26     return q?-w:w;
     27 }
     28 
     29 void link(llg x,llg y,llg z) {a[x].push_back(y); val[x].push_back(z); val[y].push_back(z); a[y].push_back(x);}
     30 
     31 void link_(llg x,llg y) {c[x].push_back(y); c[y].push_back(x);}
     32 
     33 bool cmp(const node&a,const node&b){return a.df<b.df;}
     34 
     35 void find_dad_deep(llg x,llg di)
     36 {
     37     bj[x]=1; dfs[x]=++cnt; dis[x]=di;
     38     llg w=a[x].size();
     39     for (llg i=0;i<w;i++)
     40         if (!bj[a[x][i]])
     41             {
     42                 dad[a[x][i]]=x; p[a[x][i]][0]=x; deep[a[x][i]]=deep[x]+1;
     43                 find_dad_deep(a[x][i],min(di,val[x][i]));
     44             }
     45 }
     46 
     47 void build_lca()
     48 {
     49     for (i=1;(2<<i)<=n;i++)
     50         for (j=1;j<=n;j++)
     51             p[j][i]=p[p[j][i-1]][i-1];
     52 }
     53 
     54 llg lca(llg x,llg y)
     55 {
     56     if (deep[x]<deep[y]) swap(x,y);
     57     for (llg i=18;i>=0;i--) if (deep[p[x][i]]>=deep[y]) x=p[x][i];
     58     if (x==y) return x;
     59     for (llg i=18;i>=0;i--)
     60         if (p[x][i]!=p[y][i]) {x=p[x][i]; y=p[y][i];}
     61     return dad[x];
     62 }
     63 
     64 llg st[maxn],top;
     65 
     66 void make_tree(llg x)
     67 {
     68     llg L=0,g1,g2;
     69     while(top)
     70         {
     71             g1=st[top];g2=st[top-1];L=lca(g1,x);
     72             if(deep[g2]>deep[L]) link_(g2,g1),top--;
     73             else if(deep[g2]<deep[L]) {link_(g1,L);top--;break;}
     74             else break;
     75         }
     76     if(st[top]!=L) st[++top]=L;        
     77     st[++top]=x;
     78 }
     79 
     80 void ceshi()
     81 {
     82     for (llg i=1;i<=n;i++)
     83         {
     84             llg w=c[i].size();
     85             for (llg j=0;j<w;j++) if (i<c[i][j]) cout<<i<<" "<<c[i][j]<<endl;
     86         }
     87 }
     88 
     89 llg dp(llg x)
     90 {
     91     bj[x]=1;
     92     dl[++open]=x;
     93     llg w=c[x].size(),tot=0;
     94     for (llg i=0;i<w;i++)
     95         if (!bj[c[x][i]])
     96             tot+=dp(c[x][i]);
     97     if (ss[x]) return dis[x];
     98     return min(tot,dis[x]);
     99 }
    100 
    101 int main()
    102 {
    103     freopen("a.in","r",stdin); freopen("a.out","w",stdout);
    104     cin>>n;
    105     for (i=1;i<n;i++)
    106         {
    107             llg x,y,z;
    108             x=getint(),y=getint(),z=getint();
    109             link(x,y,z);
    110         }
    111     deep[1]=1;
    112     llg ggg=(llg)1e60;
    113     find_dad_deep(1,ggg); //dis[1]=0;
    114     build_lca();
    115     cin>>T; for (i=1;i<=n;i++) bj[i]=0;
    116     while (T--)
    117         {
    118             m=getint();
    119             llg x;
    120             for (i=1;i<=open;i++) {ss[se[i]]=0; c[dl[i]].clear(); bj[dl[i]]=0;}
    121             q=0,open=0;
    122             c[1].clear(); bj[1]=0; ss[1]=0;
    123             for (i=1;i<=m;i++) {x=getint(); d[i].po=x; d[i].df=dfs[x]; q++; ss[x]=1; se[q]=x; }
    124             sort(d+1,d+m+1,cmp);
    125             top=0;
    126             if (d[1].po!=1) st[++top]=1;
    127             for (i=1;i<=m;i++) make_tree(d[i].po);
    128             while(top!=1) link_(st[top],st[top-1]),top--;
    129             //if (q<=0) printf("0
    "); else
    130             printf("%lld
    ",dp(1));
    131             //ceshi();
    132             //cout<<endl;
    133         }
    134     return 0;
    135 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    Ubuntu 12.04 安装scribe 的笔记 | 动漫驿站
    boost install on prinse 12.04 ubuntu
    basic coder » linux下获取当前程序的绝对路径
    spring 使用 groovy 的 utf8 问题
    string转化大小写(C++) | Vimer的程序世界
    linux常用命令一
    STL map与Boost unordered_map 有何不可的日志 网易博客
    本博使用的vim(gvim)相关插件整理
    【转】C++11中值得关注的几大变化 奔向C++ C++博客
    Lua 语言和C/C++集成调研小结
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/5692100.html
Copyright © 2011-2022 走看看