bzoj2286
感觉没有特别体现虚树的特点
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; const long long maxn=250002,INF=2e9; long long n,m,mi[20]; long long dp[maxn],len[maxn],node[maxn],zz[maxn]; int vis[maxn],fath[maxn]; long long aa;char cc; long long read() { aa=0;cc=getchar(); while(cc<'0'||cc>'9') cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); return aa; } int fir[maxn],nxt[2*maxn],to[2*maxn];long long v[2*maxn],e=0; void add(int x,int y,int z) { to[++e]=y;nxt[e]=fir[x];fir[x]=e;v[e]=z; to[++e]=x;nxt[e]=fir[y];fir[y]=e;v[e]=z; } int fa[maxn][20],id[maxn],end[maxn],dep[maxn],tot,maxd; void dfs(int pos,int d,long long minnum) { dep[pos]=d;id[pos]=++tot;len[pos]=minnum; maxd=max(maxd,d); for(int y=fir[pos];y;y=nxt[y]) { if(to[y]==fa[pos][0]) continue; fa[to[y]][0]=pos; dfs(to[y],d+1,min(v[y],minnum)); } end[pos]=tot; } bool cmp(const int x,const int y) { return id[x]<id[y]; } int getlca(int x,int y) { if(dep[x]!=dep[y]) { if(dep[x]<dep[y]) swap(x,y); int cha=dep[x]-dep[y]; for(int i=18;i>=0;--i) if(mi[i]<=cha){ cha-=mi[i]; x=fa[x][i]; if(!cha) break; } } int xx,yy,z; while(x!=y) { xx=x; yy=y; z=0; while(xx!=yy) { x=xx; y=yy; xx=fa[xx][z];yy=fa[yy][z]; z++; } if(z==1) {x=xx;y=yy;} } return x; } int main() { n=read(); int x,y,z,xx; for(int i=1;i<n;++i) { x=read();y=read();z=read(); add(x,y,z); } dfs(1,1,INF); mi[0]=1;for(int i=1;i<=18;++i) mi[i]=mi[i-1]*2; for(int i=1;mi[i]<=maxd+1;++i) for(int j=1;j<=n;++j) fa[j][i]=fa[fa[j][i-1]][i-1]; m=read(); for(int qaq=1;qaq<=m;++qaq) { x=read(); for(int i=1;i<=x;++i) node[i]=read(),vis[node[i]]=1; sort(node+1,node+x+1,cmp); xx=x; for(int i=2;i<=xx;++i) { z=getlca(node[i-1],node[i]); if(!vis[z]) node[++x]=z,vis[z]=2; } if(!vis[1]) node[++x]=1,vis[1]=2; sort(node+1,node+x+1,cmp); y=1;zz[1]=node[1];dp[node[1]]=0; for(int i=2;i<=x;++i) { dp[node[i]]=len[node[i]]; while(y&&id[node[i]]>end[zz[y]]) y--; fath[node[i]]=zz[y];dp[zz[y]]=0; zz[++y]=node[i]; } for(int i=x;i>1;i--) { if(vis[node[i]]==2) dp[node[i]]=min(dp[node[i]],len[node[i]]);// else dp[node[i]]=len[node[i]]; dp[fath[node[i]]]+=dp[node[i]]; } printf("%lld\n",dp[node[1]]); for(int i=1;i<=x;++i) vis[node[i]]=0; } return 0; }

浙公网安备 33010602011771号