我们可以在状态里多加一个0/1,即设 f[i][0/1][0/1] 表示以i为根的子树,以i的为子树里除去i以外是否有根节点,i是否为中转点的情况下,子树蓝边的最大总和是多少
1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<cstring>
5 #include<algorithm>
6 using namespace std;
7 char ch;
8 bool ok;
9 void read(int &x){
10 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
11 for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
12 if (ok) x=-x;
13 }
14 const int maxn=200005;
15 const int maxm=maxn*2;
16 const int inf=2147483647;
17 int n,a,b,c;
18 int f[maxn][2][2];
19 struct Graph{
20 int tot,now[maxn],son[maxm],pre[maxm],val[maxm];
21 int premax[maxn],sufmax[maxn],g[maxn];
22 void put(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
23 void add(int a,int b,int c){put(a,b,c),put(b,a,c);}
24 void dfs(int u,int fa){
25 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (v!=fa) dfs(v,u);
26 int cnt=0,sum=0; premax[0]=sufmax[0]=-inf;
27 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (v!=fa)
28 g[v]=max(f[v][0][0],f[v][0][1]+val[p]),sum+=g[v],++cnt,premax[cnt]=sufmax[cnt]=f[v][0][0]+val[p]-g[v];
29 premax[cnt+1]=sufmax[cnt+1]=-inf;
30 for (int i=1;i<=cnt;i++) premax[i]=max(premax[i],premax[i-1]);
31 for (int i=cnt;i>=1;i--) sufmax[i]=max(sufmax[i],sufmax[i+1]);
32 f[u][0][0]=sum,f[u][0][1]=cnt?f[u][0][0]+premax[cnt]:-inf,f[u][1][1]=-inf;
33 for (int p=now[u],v=son[p],i=0;p;p=pre[p],v=son[p]) if (v!=fa){i++;
34 int res=max(premax[i-1],sufmax[i+1]),tmp=sum-g[v];
35 f[u][1][0]=max(f[u][1][0],max(f[v][1][1]+val[p]+tmp,max(f[v][0][0],f[v][1][0])+tmp+max(val[p]+res,0)));
36 f[u][1][1]=max(f[u][1][1],max(f[v][0][0],f[v][1][0])+val[p]+tmp);
37 }
38 }
39 }G;
40 int main(){
41 read(n);
42 for (int i=1;i<n;i++) read(a),read(b),read(c),G.add(a,b,c);
43 G.dfs(1,0);
44 printf("%d\n",max(f[1][1][0],f[1][0][0]));
45 return 0;
46 }