f[x]=SUM{ min(f[y], z) } ( y是不重要的点)
建立虚树,然后dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #include <bits/stdc++.h> using namespace std ; const int N=3e6,M=N,inf=1e9; #define int long long int mn[N],n; int stk[N],top ; int nxt[M],go[M],w[M],hd[N],all; int f[N]; vector< int > VT[N]; void add_( int x, int y, int z){ go[++all]=y,w[all]=z,nxt[all]=hd[x],hd[x]=all; } void V_ADD( int x, int y){ VT[x].push_back(y); VT[y].push_back(x); } int dep[N],F[N][21]; int dfn[N],pool ,B[N] ; int m,a[N] ; int cmp( int i, int j){ return dfn[i]<dfn[j] ; } void init( int x, int fa){ int i,y; dfn[x]=++pool; dep[x]=dep[fa]+1; F[x][0]=fa; for (i=0;i<=19;i++) F[x][i+1]=F[F[x][i]][i]; for (i=hd[x];i;i=nxt[i]){ y=go[i]; if (y==fa) continue ; mn[y]=min(mn[x],w[i]); init(y,x); } } int lca( int x, int y){ int i; if (dep[x]<dep[y]) swap(x,y); for (i=19;i>=0;i--){ if (dep[F[x][i]]>=dep[y]) x=F[x][i]; } if (x==y) return x; for (i=19;i>=0;i--){ if (F[x][i]!=F[y][i]) x=F[x][i],y=F[y][i]; } return F[x][0]; } void dp( int x, int fa) { f[x] = 0; for ( int i = 0;i < VT[x].size();i++) { int v = VT[x][i],w = mn[v]; if (v == fa) continue ; dp(v,x); if (B[v]) { f[x] += w; } else { f[x] += min(f[v],w); } } VT[x].clear(); } void build() { sort(a + 1,a + 1 + m,cmp); top = 1; stk[top] = 1; for ( int i = 1;i <= m;i++) { if (a[i] != 1) { int l = lca(a[i],stk[top]); if (l != stk[top]) { while (top >= 2 && dfn[l] < dfn[stk[top - 1]]) { V_ADD(stk[top - 1],stk[top]); top--; } if (dfn[l] > dfn[stk[top - 1]]) { V_ADD(l,stk[top]); stk[top] = l; } else { V_ADD(l,stk[top]); top--; } } stk[++top] = a[i]; } } for ( int i = 1;i < top;i++) { V_ADD(stk[i],stk[i + 1]); } } signed main(){ int i,x,y,z; cin>>n; for (i=1;i<n;i++) cin>>x>>y>>z,add_(x,y,z),add_(y,x,z); memset (mn,127, sizeof mn); init(1,0); int tes; cin>>tes; while (tes--){ cin>>m; for (i=1;i<=m;i++){ cin>>a[i]; B[a[i]]=1; } build(); dp(1,0); cout<<f[1]<< '\n' ; for (i=1;i<=m;i++) B[a[i]]=0; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!