题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293
被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写树剖,不过这里DFS序更简单,因为都是对点到根的操作
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 #pragma comment(linker, "/STACK:102400000,102400000") 5 #define F(i,a,b) for(int i=a;i<=b;i++) 6 #define root 1,n,1 7 #define ls l,m,rt<<1 8 #define rs m+1,r,rt<<1|1 9 using namespace std; 10 11 const int N=1e5+7,DEG=20; 12 int t,n,m,x,y,dp[N],sum[N],c1[N*2],c2[N*2]; 13 struct edge{int u,v,w,lca;}p[N]; 14 vector<int>vec[N]; 15 inline void add(int x,int k,int *c){for(;x<=n*2;x+=x&-x)c[x]+=k;} 16 inline int ask(int x,int *c){int an=0;while(x)an+=c[x],x-=x&-x;return an;} 17 //LCA+dfs序 18 int ed,g[N],nxt[2*N],v[2*N],fa[N][DEG],dep[N],idx,l[2*N],r[2*N]; 19 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} 20 21 void LCA_dfs(int u,int pre){ 22 dep[u]=dep[pre]+1,fa[u][0]=pre,l[u]=++idx; 23 F(i,1,DEG-1)fa[u][i]=fa[fa[u][i-1]][i-1]; 24 for(int i=g[u];~i;i=nxt[i])if(v[i]!=pre)LCA_dfs(v[i],u); 25 r[u]=++idx; 26 } 27 28 int LCA(int a,int b){ 29 if(dep[a]>dep[b])a^=b,b^=a,a^=b; 30 if(dep[a]<dep[b])F(i,0,DEG-1)if((dep[b]-dep[a])&(1<<i))b=fa[b][i]; 31 if(a!=b)for(int i=DEG-1;i<0?a=fa[a][0]:0,i>=0;i--) 32 if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i]; 33 return a; 34 } 35 36 void fuck(int s,int fa){ 37 dp[s]=sum[s]=0; 38 for(int i=g[s];~i;i=nxt[i])if(v[i]!=fa)fuck(v[i],s),sum[s]+=dp[v[i]]; 39 dp[s]=sum[s]; 40 for(int i=0;i<vec[s].size();i++){ 41 int uu=p[vec[s][i]].u,vv=p[vec[s][i]].v; 42 int tmp=ask(l[uu],c1)+ask(l[vv],c1)-ask(l[uu],c2)-ask(l[vv],c2)+sum[s]; 43 dp[s]=max(dp[s],tmp+p[vec[s][i]].w); 44 } 45 add(l[s],sum[s],c1),add(r[s],-sum[s],c1); 46 add(l[s],dp[s],c2),add(r[s],-dp[s],c2); 47 } 48 void init(){ 49 F(i,1,n)g[i]=-1,vec[i].clear();ed=idx=0; 50 F(i,1,n*2)c1[i]=c2[i]=0; 51 } 52 53 int main(){ 54 scanf("%d",&t); 55 while(t--){ 56 scanf("%d%d",&n,&m); 57 init(); 58 F(i,1,n-1)scanf("%d%d",&x,&y),adg(x,y),adg(y,x); 59 LCA_dfs(1,1); 60 F(i,1,m){ 61 scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w); 62 p[i].lca=LCA(p[i].u,p[i].v); 63 vec[p[i].lca].push_back(i); 64 } 65 fuck(1,0); 66 printf("%d ",dp[1]); 67 } 68 return 0; 69 }