【bzoj2286】[Sdoi2011]消耗战
虚树入门题;
#include<cstdio> #include<cstring> #include<algorithm> #include<ctime> #include<cmath> #include<iostream> using namespace std; #define LL long long #define pii pair<int,int> #define up(i,j,n) for(int i=(j);i<=(n);i++) #define FILE "dealing" int read(){ int f=1,x=0,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return f*x; } const int maxn=505000,inf=1000000000; int n,m,lim,k; struct node{int y,next,v;}e[maxn],E[maxn]; LL linkk[maxn],len=0,linker[maxn],pre[maxn],vis[maxn],Len,d[maxn][31],fa[maxn][31],dfs_clock,dep[maxn],q[maxn],top=0,f[maxn]; pii a[maxn]; void insert(int x,int y,int v){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].v=v;} void insert2(int x,int y,int v){E[++Len].y=y;E[Len].next=linker[x];linker[x]=Len;E[Len].v=v;} void dfs(int x){ pre[x]=++dfs_clock; for(int i=linker[x];i;i=E[i].next){ if(E[i].y==fa[x][0])continue; fa[E[i].y][0]=x; d[E[i].y][0]=E[i].v; dep[E[i].y]=dep[x]+1; dfs(E[i].y); } } int lca(int x,int y){ if(dep[x]>dep[y])swap(x,y); for(int i=lim;i>=0;i--)if(dep[y]-dep[x]>=(1<<i))y=fa[y][i]; if(x==y)return x; for(int i=lim;i>=0;i--)if(fa[y][i]!=fa[x][i])x=fa[x][i],y=fa[y][i]; return fa[x][0]; } LL fmin(LL x,LL y){ if(dep[x]>dep[y])swap(x,y); LL Min=inf; for(int i=lim;i>=0;i--)if(dep[y]-dep[x]>=(1<<i))Min=min((LL)Min,d[y][i]),y=fa[y][i]; return Min; } void dp(int x,int fa,int w){ if(vis[x]&&x!=1){f[x]=w;return;} else { f[x]=0; for(int i=linkk[x];i;i=e[i].next){ if(e[i].y==fa)continue; dp(e[i].y,x,e[i].v); f[x]+=f[e[i].y]; } if(x!=1)f[x]=min(f[x],(LL)w); } } void clear(int x,int fa){ for(int i=linkk[x];i;i=e[i].next){ if(e[i].y==fa)continue; clear(e[i].y,x); } f[x]=0; linkk[x]=0; } int main(){ //freopen("dealing.in","r",stdin); //freopen("dealing.out","w",stdout); n=read();lim=(int)log2(n*1.0+1)+1; up(i,1,n-1){ int x=read(),y=read(),v=read(); insert2(x,y,v);insert2(y,x,v); } dfs(1); up(j,1,lim)up(i,1,n)fa[i][j]=fa[fa[i][j-1]][j-1],d[i][j]=min(d[i][j-1],d[fa[i][j-1]][j-1]); m=read(); while(m--){ k=read()+1;a[k].second=1; up(i,1,k-1)a[i].second=read(); up(i,1,k)a[i].first=pre[a[i].second],vis[a[i].second]=1;vis[1]=0; sort(a+1,a+k+1); up(i,1,k){ int x=a[i].second; if(!top){q[++top]=x;continue;} int Lca=lca(x,q[top]); if(Lca==q[top]){q[++top]=x;continue;} while(dep[q[top-1]]>dep[Lca]){ LL v=fmin(q[top],q[top-1]); insert(q[top],q[top-1],v);insert(q[top-1],q[top],v); top--; } LL v=fmin(Lca,q[top]); insert(Lca,q[top],v);insert(q[top],Lca,v); top--; if(q[top]!=Lca)q[++top]=Lca;q[++top]=x; } while(top!=1){ LL v=fmin(q[top],q[top-1]); insert(q[top],q[top-1],v); insert(q[top-1],q[top],v); top--; } dp(1,0,0);top=0; printf("%lld\n",f[1]); clear(1,0); up(i,1,k)vis[a[i].second]=0;len=0; } return 0; }