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

      还是虚树恩。。模板都能打挂QAQ

      先在原树上预处理出mndis[i],表示根节点到节点i 路径上边权的最小值(就是断开i与根的联系的最小花费)

      建完虚树在虚树上跑树形DP。。f[i]表示断开  i 所在子树内所有有资源的节点  与根节点的联系的最小花费。

      若i 节点没资源:f[i]=min( mndis[i] , sigma(f[j]) ),(j是i的儿子,且j所在子树内有有资源的节点)。

      若i 节点有资源:f[i]=mndis[i]。。。

      链剖大法好。。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring> 
      4 #include<algorithm>
      5 #define ll long long
      6 using namespace std;
      7 const int maxn=250233;
      8 const int inf=1002333333;
      9 struct zs{
     10     int too,pre,dis;
     11 }e[maxn<<1];
     12 struct zs1{
     13     int too,pre;
     14 }e1[maxn<<1];
     15 int last[maxn],tot,last1[maxn],tot1;
     16 int mndis[maxn],sz[maxn],st[maxn],top;
     17 int dfn[maxn],dep[maxn],bel[maxn],fa[maxn],size[maxn],tim;
     18 int have[maxn],poi[maxn];
     19 int i,j,k,K,n,m,a,b,c;
     20 ll f[maxn];
     21  
     22  
     23 int ra;char rx;
     24 inline int read(){
     25     rx=getchar(),ra=0;
     26     while(rx<'0'||rx>'9')rx=getchar();
     27     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     28 }
     29  
     30  
     31 inline void insert(int a,int b,int c){
     32     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot;
     33     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
     34 }
     35 inline void ins(int a,int b){
     36 //  printf("  %d-->%d
    ",a,b);
     37     e1[++tot1].too=b,e1[tot1].pre=last1[a],last1[a]=tot1;
     38 }
     39  
     40  
     41 void dfs(int x){
     42     dep[x]=dep[fa[x]]+1,size[x]=1;
     43     for(int i=last[x];i;i=e[i].pre)
     44         if(e[i].too!=fa[x])
     45             fa[e[i].too]=x,
     46             mndis[e[i].too]=mndis[x]<e[i].dis?mndis[x]:e[i].dis,
     47             dfs(e[i].too),
     48             size[x]+=size[e[i].too];
     49 }
     50 void dfs2(int x,int chain){
     51     int i,mxpos=0;bel[x]=chain,dfn[x]=++tim;
     52     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&size[e[i].too]>=size[mxpos])mxpos=e[i].too;
     53     if(!mxpos)return;
     54     dfs2(mxpos,chain);
     55     for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mxpos)dfs2(e[i].too,e[i].too);
     56 }
     57 inline int getlca(int a,int b){
     58     if(dep[bel[a]]<dep[bel[a]])swap(a,b);
     59     while(bel[a]!=bel[b]){
     60         a=fa[bel[a]];
     61         if(dep[bel[a]]<dep[bel[b]])swap(a,b);
     62     }
     63     return dep[a]<dep[b]?a:b;
     64 }
     65  
     66  
     67 inline void build(){
     68     register int i,lca;
     69     st[top=1]=1;
     70     for(i=1;i<=K;i++){
     71         lca=getlca(poi[i],st[top]);
     72         while(dfn[st[top]]>dfn[lca])
     73             if(dfn[st[--top]]<=dfn[lca]){
     74                 ins(lca,st[top+1]);
     75                 if(st[top]!=lca)st[++top]=lca;
     76             }else ins(st[top],st[top+1]);//,puts("");
     77         st[++top]=poi[i];
     78     }
     79     while(top>1)ins(st[top-1],st[top]),top--;
     80 }
     81 void query(int x){
     82     int i,to;
     83     f[x]=sz[x]=0;
     84     if(have[x]==m){f[x]=mndis[x],sz[x]=1;return;}
     85     for(to=e1[i=last1[x]].too;i;to=e1[i=e1[i].pre].too){
     86         query(to);
     87         if(sz[to])f[x]+=f[to],sz[x]+=sz[to];
     88     }
     89     if(x!=1&&mndis[x]<f[x])f[x]=mndis[x];
     90 }
     91  
     92  
     93 bool cmp(int a,int b){return dfn[a]<dfn[b];}
     94 int main(){
     95     n=read();
     96     for(i=1;i<n;i++)a=read(),b=read(),c=read(),insert(a,b,c);
     97     mndis[1]=inf,dfs(1),dfs2(1,1);
     98 //  for(i=1;i<=n;i++)printf("   %d
    ",mndis[i]);
     99      
    100     for(m=read();m;m--){
    101         K=read();for(i=1;i<=K;i++)have[poi[i]=read()]=m;
    102          
    103         sort(poi+1,poi+1+K,cmp),
    104         build(),
    105         query(1),
    106         printf("%lld
    ",f[1]);
    107          
    108         if(m>1){for(i=tot1;i;i--)last1[e1[i].too]=0;last1[1]=tot1=0;}
    109     }
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    作业十三
    作业十二
    第十一次作业
    编译原理第十次作业
    P3388 【模板】割点(割顶) 题解 (Tarjan)
    BuaacodingT141 microhhh的回城 题解(模拟)
    P2055 [ZJOI2009]假期的宿舍 题解(二分图)
    P2764 最小路径覆盖问题 题解(二分图)
    2019.2-2019.3 TO-DO LIST
    P3369 【模板】普通平衡树 题解(Splay/FHQ)
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5187235.html
Copyright © 2011-2022 走看看