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 }
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 }