Point Division treatment ... What the hell! Konjac Konjac How to do so Mulberry heart%>_<%
Orz Hzwer
Konjac Konjac to add something Hzwer didn't say:
(1) for negative plant weights set to-1, positive is set to +1
(2) The last paragraph is about how to use the new subtree's f[] value to find ans and update g[]
1 /**************************************************************2 problem:36973 User:rausen4 language:c++5 result:accepted6 time:1752 Ms7 memory:15924 KB8 ****************************************************************/9 Ten#include <cstdio> One#include <algorithm> A - using namespacestd; - Const intN =100005; the - structEdge { - intNext, to, V; - Edge () {} +Edgeint_n,int_t,int_v): Next (_n), to (_t), V (_v) {} -} e[n <<1]; + A intfirst[n], tot; at - structTree_node { - intsz, DEP, DIS; - BOOLVis; - } Tr[n]; - in intN, K; - intCnt[n <<1]; to Long LongF[n <<1][2], G[n <<1][2], ans; + intRoot, Maxsz; - intmx_dep, MX; the *InlineintRead () { $ intx =0;Panax Notoginseng CharCH =GetChar (); - while(Ch <'0'||'9'<ch) theCH =GetChar (); + while('0'<= CH && Ch <='9') { Ax = x *Ten+ CH-'0'; theCH =GetChar (); + } - returnx; $ } $ - voidAdd_edges (intXintYintz) { -E[++tot] = Edge (first[x], y, z), first[x] =tot; theE[++tot] = Edge (First[y], x, z), first[y] =tot; - }Wuyi the voidDfsintPintFaintSZ) { - intX, y, Maxsz =0; WuTR[P].SZ =1; - for(x = first[p]; x; x =e[x].next) About if((y = e[x].to)! = FA &&!Tr[y].vis) { $ dfs (Y, p, sz); -Tr[p].sz + =Tr[y].sz; -Maxsz =Max (Maxsz, TR[Y].SZ); - } AMaxsz = Max (Maxsz, Sz-tr[p].sz); + if(Maxsz <Maxsz) theRoot = p, Maxsz =Maxsz; - } $ the intGet_root (intPintSZ) { theMaxsz = N <<1; theDFS (p,0, SZ); the returnRoot; - } in the voidDfs (intPintFA) { the intx, y; AboutMX_DEP =Max (MX_DEP, TR[P].DEP); the if(Cnt[tr[p].dis]) ++f[tr[p].dis][1]; the Else++f[tr[p].dis][0]; the++Cnt[tr[p].dis]; + for(x = first[p]; x; x =e[x].next) - if((y = e[x].to)! = FA &&!Tr[y].vis) { theTR[Y].DEP = TR[P].DEP +1, Tr[y].dis = Tr[p].dis +e[x].v;Bayi Dfs (y, p); the } the--Cnt[tr[p].dis]; - } - the voidCalintp) { the intx, Y, J; theMX =0, g[n][0] =1; the for(x = first[p]; x; x =e[x].next) - if(!tr[y =E[x].to].vis) { theTr[y].dis = n + e[x].v, TR[Y].DEP =1, MX_DEP =1; the Dfs (y, p); theMX =max (MX, MX_DEP);94Ans + = (g[n][0] -1) * f[n][0]; the for(j =-mx_dep; J <= Mx_dep; + +j) theAns + = g[n-j][1] * f[n + j][1] + g[n-j][0] * f[n + j][1] + g[n-j][1] * f[n + j][0]; the for(j = n-mx_dep; J <= N + mx_dep; + +)j) {98g[j][0] + = f[j][0], g[j][1] + = f[j][1]; Aboutf[j][0] = f[j][1] =0; - }101 }102 for(j = n-mx; J <= n + mx; + +)j)103g[j][0] = g[j][1] =0;104 } the 106 voidWorkintPintSZ) {107 intRoot =get_root (P, SZ), x, y;108Tr[root].vis =1;109 cal (root); the for(x = first[root]; x; x =e[x].next)111 if(!tr[y =E[x].to].vis) the Work (y, tr[y].sz);113 } the the intMain () { the intI, x, Y, Z;117n =read ();118 for(i =1; I < n; ++i) {119x = Read (), y = read (), z =read (); -Add_edges (x, Y, z?)1: -1);121 }122Work1, n);123printf"%lld\n", ans);124 return 0; the}View Code
(In fact, I think ...) Point Division to achieve 1600ms is the limit, rank the front of the two should use a special skill ♂ skillfully )
BZOJ3697 the path of the person who picked the medicine