虚树裸题。
23333以后memset千万慎用。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 250050 #define maxe 500050 #define inf 0x7f7f7f7f7f7f7f7fLL using namespace std; struct edge { long long v,w,nxt; }e[maxe],tr[maxe<<2]; struct ask { long long pnt,dfn; }q[maxv]; using namespace std; long long n,x,y,z,g[maxv],nume=0,numt=0,gt[maxv],dfn[maxv],dis[maxv],anc[maxv][24],mn[maxv][24],dep[maxv]; long long m,k,stack[maxv],top=0,times=0,val[maxv],hash[maxv],now_cnt,fath[maxv],laste=0; long long read() { long long data=0;char ch; while (ch<'0' || ch>'9') ch=getchar(); do { data=data*10+ch-'0'; ch=getchar(); }while (ch>='0' && ch<='9'); return data; } bool cmp(ask x,ask y) { return x.dfn<y.dfn; } void addedge(long long u,long long v,long long w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } void addtree(long long u,long long v,long long w) { tr[++numt].v=v; tr[numt].w=w; if (gt[u]<=laste) tr[numt].nxt=0; else tr[numt].nxt=gt[u]; gt[u]=numt; } void dfs(long long x) { dfn[x]=++times; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if (v!=anc[x][0]) { anc[v][0]=x;mn[v][0]=e[i].w;dis[v]=dis[x]+e[i].w; dep[v]=dep[x]+1; dfs(v); } } } void get_table() { for (long long e=1;e<=22;e++) for (long long i=1;i<=n;i++) { anc[i][e]=anc[anc[i][e-1]][e-1]; mn[i][e]=min(mn[i][e-1],mn[anc[i][e-1]][e-1]); } } void reset() { top=0; } long long lca(long long x,long long y) { if (dep[x]<dep[y]) swap(x,y); for (long long e=22;e>=0;e--) { if ((dep[anc[x][e]]>=dep[y]) && (anc[x][e])) x=anc[x][e]; } if (x==y) return x; for (long long e=22;e>=0;e--) { if (anc[x][e]!=anc[y][e]) { x=anc[x][e]; y=anc[y][e]; } } return anc[x][0]; } long long ask(long long x,long long y) { long long ret=inf; for (long long e=22;e>=0;e--) { if ((dep[anc[x][e]]>=dep[y]) && (anc[x][e])) { ret=min(ret,mn[x][e]); x=anc[x][e]; } } return ret; } void dp(long long x) { val[x]=0; for (long long i=gt[x];i;i=tr[i].nxt) { long long v=tr[i].v; if (v!=fath[x]) { dp(v); if (hash[v]==now_cnt) val[x]+=tr[i].w; else val[x]+=min(val[v],tr[i].w); } } } void work() { k=read(); for (long long i=1;i<=k;i++) { x=read(); q[i].pnt=x;q[i].dfn=dfn[x]; hash[x]=now_cnt; } sort(q+1,q+k+1,cmp); stack[++top]=1; for (long long i=1;i<=k;i++) { long long x=q[i].pnt,fr=stack[top],se=stack[top-1]; long long t=lca(x,fr); if (t==fr) stack[++top]=x; else { for (;;) { long long ret; fr=stack[top];se=stack[top-1]; long long t=lca(x,fr); if (dfn[t]<dfn[se]) {ret=ask(fr,se);addtree(fr,se,ret);addtree(se,fr,ret);fath[fr]=se;top--;} else if (dfn[t]==dfn[se]) {ret=ask(fr,se);addtree(fr,se,ret);addtree(se,fr,ret);fath[fr]=se;top--;break;} else { long long ret=ask(fr,t); addtree(fr,t,ret);addtree(t,fr,ret); stack[top]=t;fath[fr]=t;break; } } stack[++top]=x; } } while (top>=2) { long long fr=stack[top],se=stack[top-1],ret=ask(fr,se); addtree(fr,se,ret); addtree(se,fr,ret); fath[fr]=se; top--; } dp(1);printf("%lld\n",val[1]); laste=numt; return; } int main() { n=read(); for (long long i=1;i<=n-1;i++) { x=read();y=read();z=read(); addedge(x,y,z);addedge(y,x,z); } dfs(1); get_table(); m=read(); for (long long i=1;i<=m;i++) { reset(); now_cnt=i; work(); } return 0; }