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\n",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\n",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

 

posted @ 2017-01-18 22:47  SD_le  阅读(178)  评论(0编辑  收藏  举报
重置按钮