#include <bits/stdc++.h> using namespace std; void imax(int &a, int b){ a=max(a, b); } void imin(int &a, int b){ a=min(a, b); } void lmax(long long &a, long long b){ a=max(a, b); } void lmin(long long &a, long long b){ a=min(a, b); } /* WARNING: I'm using strange bracket style! */ #define a0 first.first #define a1 first.second #define a2 second.first #define a3 second.second const long long INF=1ll<<60; const int SIZE=300000; const int BUCKET=2000; const int MID=1000; vector <pair <pair <long long, long long>, pair <long long, long long> > > V[SIZE]; vector <pair <int, int> > graph[SIZE]; long long DP[2][2][2][2][2][BUCKET]; long long BIGDP[SIZE][4]; bool visited[SIZE]; int n, x, y, z; pair <pair <long long, long long>, pair <long long, long long> > solve3(int u){ const int VIC=min({max(5, (int)sqrt(9.0*V[u].size())), 400, (int)V[u].size()+1}); const int A=MID-VIC, B=MID+VIC; for (int si=0; si<=1; si++) for (int b1=0; b1<=1; b1++) for (int b2=0; b2<=1; b2++) for (int b3=0; b3<=1; b3++) for (int b4=0; b4<=1; b4++) for (int bill=A-1; bill<=B+1; bill++) DP[si][b1][b2][b3][b4][bill]=-INF; DP[0][0][0][0][0][MID]=0; bool si=0; for (auto item: V[u]) { for (int b1=0; b1<=1; b1++) for (int b2=0; b2<=1; b2++) for (int b3=0; b3<=1; b3++) for (int b4=0; b4<=1; b4++) if (!((b2 && b3) || (b2 && b4) || (b3 && b4))) for (int bill=A; bill<=B; bill++) { DP[!si][b1][b2][b3][b4][bill]=-INF; if (b2==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][0][b3][b4][bill]+item.a1); if (b3==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][0][b4][bill]+item.a2); if (b4==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][0][bill]+item.a3); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill]+item.a0); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill-1]+item.a1); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1^1][b2][b3][b4][bill]+item.a2); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill+1]+item.a3); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill]); } si^=1; } return {{DP[si][0][0][0][0][MID], DP[si][0][1][0][0][MID]}, {DP[si][0][0][1][0][MID], DP[si][0][0][0][1][MID]}}; } void dfs(int u){ visited[u]=true; long long parent=-INF; for (auto [v, price]: graph[u]) if (!visited[v]) dfs(v), V[u].push_back({{BIGDP[v][0], BIGDP[v][1]}, {BIGDP[v][2], BIGDP[v][3]}}); else parent=price; random_shuffle(V[u].begin(), V[u].end()); auto S=solve3(u); BIGDP[u][0]=max(S.a3+parent, S.a0); BIGDP[u][1]=S.a0+parent; BIGDP[u][2]=S.a1+parent; BIGDP[u][3]=S.a2+parent; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n; for (int i=1; i<n; i++) cin>>x>>y>>z, graph[x].push_back({y, z}), graph[y].push_back({x, z}); return dfs(1), cout<<BIGDP[1][0]<<"\n", 0; }
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 | #include <bits/stdc++.h> using namespace std; void imax(int &a, int b){ a=max(a, b); } void imin(int &a, int b){ a=min(a, b); } void lmax(long long &a, long long b){ a=max(a, b); } void lmin(long long &a, long long b){ a=min(a, b); } /* WARNING: I'm using strange bracket style! */ #define a0 first.first #define a1 first.second #define a2 second.first #define a3 second.second const long long INF=1ll<<60; const int SIZE=300000; const int BUCKET=2000; const int MID=1000; vector <pair <pair <long long, long long>, pair <long long, long long> > > V[SIZE]; vector <pair <int, int> > graph[SIZE]; long long DP[2][2][2][2][2][BUCKET]; long long BIGDP[SIZE][4]; bool visited[SIZE]; int n, x, y, z; pair <pair <long long, long long>, pair <long long, long long> > solve3(int u){ const int VIC=min({max(5, (int)sqrt(9.0*V[u].size())), 400, (int)V[u].size()+1}); const int A=MID-VIC, B=MID+VIC; for (int si=0; si<=1; si++) for (int b1=0; b1<=1; b1++) for (int b2=0; b2<=1; b2++) for (int b3=0; b3<=1; b3++) for (int b4=0; b4<=1; b4++) for (int bill=A-1; bill<=B+1; bill++) DP[si][b1][b2][b3][b4][bill]=-INF; DP[0][0][0][0][0][MID]=0; bool si=0; for (auto item: V[u]) { for (int b1=0; b1<=1; b1++) for (int b2=0; b2<=1; b2++) for (int b3=0; b3<=1; b3++) for (int b4=0; b4<=1; b4++) if (!((b2 && b3) || (b2 && b4) || (b3 && b4))) for (int bill=A; bill<=B; bill++) { DP[!si][b1][b2][b3][b4][bill]=-INF; if (b2==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][0][b3][b4][bill]+item.a1); if (b3==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][0][b4][bill]+item.a2); if (b4==1) lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][0][bill]+item.a3); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill]+item.a0); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill-1]+item.a1); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1^1][b2][b3][b4][bill]+item.a2); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill+1]+item.a3); lmax(DP[!si][b1][b2][b3][b4][bill], DP[si][b1][b2][b3][b4][bill]); } si^=1; } return {{DP[si][0][0][0][0][MID], DP[si][0][1][0][0][MID]}, {DP[si][0][0][1][0][MID], DP[si][0][0][0][1][MID]}}; } void dfs(int u){ visited[u]=true; long long parent=-INF; for (auto [v, price]: graph[u]) if (!visited[v]) dfs(v), V[u].push_back({{BIGDP[v][0], BIGDP[v][1]}, {BIGDP[v][2], BIGDP[v][3]}}); else parent=price; random_shuffle(V[u].begin(), V[u].end()); auto S=solve3(u); BIGDP[u][0]=max(S.a3+parent, S.a0); BIGDP[u][1]=S.a0+parent; BIGDP[u][2]=S.a1+parent; BIGDP[u][3]=S.a2+parent; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n; for (int i=1; i<n; i++) cin>>x>>y>>z, graph[x].push_back({y, z}), graph[y].push_back({x, z}); return dfs(1), cout<<BIGDP[1][0]<<"\n", 0; } |