• bzoj 3611: [Heoi2014]大工程 && bzoj 2286: [Sdoi2011消耗战


          放波建虚树的模板。

          大概是用一个栈维护根节点到当前关键点的一条链,把其他深度大于lca的都弹出去。

          每次做完记得复原。

          还有sort的时候一定要加cmp!!!

          bzoj 3611

          

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define N 1000005
      6 #define ll long long
      7 #define inf 0x3f3f3f3f
      8 using namespace std;
      9 inline int read()
     10 {
     11     int p=0;char c=getchar();
     12     while(c<'0'||c>'9')c=getchar();
     13     while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();
     14     return p;
     15 }
     16 int n;
     17 int dfn[N];
     18 int fa[N][21];
     19 int dep[N],z;
     20 int head[N],ver[N*2],nxt[N*2],tot;
     21 void add(int a,int b)
     22 {
     23     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;
     24 }
     25 void dfs(int x,int f)
     26 {
     27     dfn[x]=++z;
     28     for(int i=head[x];i;i=nxt[i])
     29     {
     30         if(ver[i]==f)continue;
     31         dep[ver[i]]=dep[x]+1;
     32         fa[ver[i]][0]=x;
     33         dfs(ver[i],x);
     34     }
     35     return ;
     36 }
     37 void lca()
     38 {
     39     for(int i=1;i<=20;i++)
     40     {
     41         for(int j=1;j<=n;j++)
     42         {
     43             fa[j][i]=fa[fa[j][i-1]][i-1];
     44         }
     45     }return ;
     46 }
     47 int lca(int x,int y)
     48 {
     49     if(dep[x]<dep[y])swap(x,y);
     50     for(int i=20;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
     51     if(x==y)return x;
     52     for(int i=20;i>=0;i--)
     53     {
     54         if(fa[x][i]!=fa[y][i])
     55         {
     56             x=fa[x][i];y=fa[y][i];
     57         }
     58     }
     59     return fa[x][0];
     60 }
     61 bool cmp(int x,int y)
     62 {
     63     return dfn[x]<dfn[y];
     64 }
     65 int now[N],cnt;
     66 int st[N],top;
     67 int dian[N],num;
     68 int vis[N];
     69 void build()
     70 {
     71     tot=0;
     72     st[1]=1;top=1;
     73     for(int i=1;i<=cnt;i++)
     74     {
     75         if(now[i]==1)continue;
     76         int v=now[i];
     77         int la=lca(st[top],v);
     78         if(st[top]!=la)
     79         {
     80             while(top>=2&&dep[st[top-1]]>dep[la])
     81             {
     82                 add(st[top-1],st[top]);top--;
     83             }
     84             add(la,st[top]);top--;
     85             if(st[top]!=la)st[++top]=la;
     86         }
     87         st[++top]=v;
     88     }
     89     while(top>=2)add(st[top-1],st[top]),top--;
     90 }
     91 ll ans1;
     92 int ans2,ans3;
     93 int size[N];
     94 int mx1[N],mx2[N],mn1[N],mn2[N];
     95 void dfs(int x)
     96 {
     97     dian[++num]=x;
     98     if(vis[x])size[x]=1;
     99     else size[x]=0;
    100     mx1[x]=mx2[x]=0;
    101     mn1[x]=mn2[x]=inf;
    102     for(int i=head[x];i;i=nxt[i])
    103     {
    104         int quan=dep[ver[i]]-dep[x];
    105         dfs(ver[i]);
    106         if(vis[ver[i]])mn1[ver[i]]=0;
    107         if(mn1[ver[i]]+quan<mn1[x])
    108         {
    109             mn2[x]=mn1[x];
    110             mn1[x]=mn1[ver[i]]+quan;
    111         }
    112         else if(mn1[ver[i]]+quan<mn2[x])mn2[x]=mn1[ver[i]]+quan;
    113         ans1+=(long long)size[ver[i]]*(cnt-size[ver[i]])*quan;
    114         size[x]+=size[ver[i]];
    115         if(mx1[ver[i]]+quan>mx1[x])
    116         {
    117             mx2[x]=mx1[x];
    118             mx1[x]=mx1[ver[i]]+quan;
    119         }
    120         else if(mx1[ver[i]]+quan>mx2[x])mx2[x]=mx1[ver[i]]+quan;
    121     }
    122     if(vis[x])ans2=min(ans2,mn1[x]);
    123     else ans2=min(ans2,mn1[x]+mn2[x]);
    124     if(mx2[x])ans3=max(ans3,mx1[x]+mx2[x]);
    125     else if(vis[x])ans3=max(ans3,mx1[x]);
    126 }
    127 int main()
    128 {
    129     n=read();
    130     int t1,t2,t3,t4;
    131     for(int i=1;i<n;i++)
    132     {
    133         t1=read();t2=read();
    134         add(t1,t2);add(t2,t1);
    135     }
    136     dep[1]=1;
    137     dfs(1,-1);
    138     lca();
    139     int q,k;
    140     q=read();
    141     memset(head,0,sizeof(head));
    142     for(int i=1;i<=q;i++)
    143     {
    144         ans1=0;ans2=inf;ans3=0;
    145         k=read();cnt=k;num=0;
    146         for(int j=1;j<=k;j++)now[j]=read(),vis[now[j]]=1;
    147         sort(now+1,now+k+1,cmp);
    148         build();dfs(1);
    149         for(int j=1;j<=cnt;j++)vis[now[j]]=0;
    150         for(int j=1;j<=num;j++)head[dian[j]]=0;num=0;
    151         printf("%lld %d %d
    ",ans1,ans2,ans3);
    152     }
    153     return 0;
    154 }
    View Code

         

           bzoj2286

           

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define N 500005
      6 #define inf 0x3f3f3f3f
      7 using namespace std;
      8 int n;
      9 int head[N],ver[N*2],nxt[N*2],quan[N*2],tot;
     10 inline int read()
     11 {
     12     int p=0;char c=getchar();
     13     while(c<'0'||c>'9')c=getchar();
     14     while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar();
     15     return p;
     16 }
     17 void add(int a,int b,int c)
     18 {
     19     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;quan[tot]=c;
     20 }
     21 int fa[N][22],mn[N][22],dep[N];
     22 void lca()
     23 {
     24     for(int i=1;i<=20;i++)
     25     {
     26         for(int j=1;j<=n;j++)
     27         {
     28             fa[j][i]=fa[fa[j][i-1]][i-1];
     29             mn[j][i]=min(mn[j][i-1],mn[fa[j][i-1]][i-1]);
     30         }
     31     }
     32     return ;
     33 }
     34 int lca(int x,int y)
     35 {
     36     if(dep[x]<dep[y])swap(x,y);
     37     for(int i=20;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
     38     if(x==y)return x;
     39     for(int i=20;i>=0;i--)
     40     {
     41         if(fa[x][i]!=fa[y][i])
     42         {
     43             x=fa[x][i];y=fa[y][i];
     44         }
     45     }
     46     return fa[x][0];
     47 }
     48 int z,dfn[N];
     49 void dfs(int x,int f)
     50 {
     51     dfn[x]=++z;
     52     for(int i=head[x];i;i=nxt[i])
     53     {
     54         if(ver[i]==f)continue;
     55         dep[ver[i]]=dep[x]+1;
     56         fa[ver[i]][0]=x;
     57         mn[ver[i]][0]=quan[i];
     58         dfs(ver[i],x);
     59     }return ;
     60 }
     61 int now[N],cnt;
     62 int vis[N],st[N],top;
     63 int dian[N],num;
     64 int qur(int x,int y)
     65 {
     66     int ans=inf;
     67     for(int i=20;i>=0;i--)
     68     {
     69         if(dep[fa[x][i]]>=dep[y])
     70         {
     71             ans=min(ans,mn[x][i]);
     72             x=fa[x][i];
     73         }
     74     }
     75     return ans;
     76 }
     77 void build()
     78 {
     79     tot=0;
     80     st[1]=1;top=1;
     81     for(int i=1;i<=cnt;i++)
     82     {
     83         if(now[i]==1)continue;
     84         int v=now[i];
     85         int la=lca(st[top],v);
     86         if(la!=st[top])
     87         {
     88             while(top>=2&&dep[st[top-1]]>dep[la])
     89             {
     90                 add(st[top-1],st[top],qur(st[top],st[top-1])),top--;
     91             }
     92             add(la,st[top],qur(st[top],la));top--;
     93             if(la!=st[top])st[++top]=la;
     94         }
     95         st[++top]=v;
     96     }
     97     while(top>=2)
     98     {
     99         add(st[top-1],st[top],qur(st[top],st[top-1])),top--;
    100     }
    101     return ;
    102 }
    103 long long f[N];
    104 bool cmp(int x,int y)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    105 {
    106     return dfn[x]<dfn[y];
    107 }
    108 void dp(int x)
    109 {
    110     dian[++num]=x;f[x]=0;
    111     for(int i=head[x];i;i=nxt[i])
    112     {
    113         dp(ver[i]);
    114         if(vis[ver[i]])f[x]+=quan[i];
    115         else f[x]+=min((long long)quan[i],f[ver[i]]);
    116     }
    117     return ;
    118 }
    119 int main()
    120 {
    121     n=read();
    122     int t1,t2,t3,t4;
    123     for(int i=1;i<n;i++)
    124     {
    125         t1=read();t2=read();t3=read();
    126         add(t1,t2,t3);add(t2,t1,t3);
    127     }
    128     mn[1][0]=inf;dep[1]=1;
    129     dfs(1,-1);
    130     lca();
    131     memset(head,0,sizeof(head));
    132     int q,k;
    133     q=read();
    134     for(int i=1;i<=q;i++)
    135     {
    136         k=read();cnt=k;num=0;
    137         for(int j=1;j<=k;j++)
    138         {
    139             now[j]=read();vis[now[j]]=1;
    140         }
    141         sort(now+1,now+k+1,cmp);build();
    142         dp(1);
    143         printf("%lld
    ",f[1]);
    144         for(int j=1;j<=k;j++)vis[now[j]]=0;
    145         for(int j=1;j<=num;j++)head[dian[j]]=0;
    146     }
    147     return 0;
    148 }
    View Code
  • 相关阅读:
    inlineblock详解
    jvisualvm JavaVisualVM 远程连接
    C#解决XML反序列化空格值被忽略的问题
    modbus通讯协议
    C语言经典易错题目
    Redis集群报错Node Is Not Empty,Either The Node Already Knows Other Nodes
    GDB的GEF插件
    LLVM基础学习:使用VSCode+GDB 调试 outoftree 的 LLVM Pass 的配置
    GDB 的WEB前端GDBgui
    安全分析工具dr checker的安装
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6298412.html
Copyright © 2020-2023  润新知