Problem descriptiononce Upon a time, in the mystical continent, there are a frog kingdom, ruled by the oldest frog, the Eld Er. The kingdom consists of N cities, numbered from east to west. The 1-th city, which are located to the east of others, are the capital. Except the capital, links none or several cities to the west, and exactly one city to the east.
There is some significant news happening in some cities every day. The Elder wants to know them as soon as possible. So, that's the job of journalist frogs, who run faster than any other frog. Once Some tremendous news happen in a city, the journalist in this city would take the message and run to the capital. Once it reach another city, it can either continue running, or stop at the and let another journalist to transport. The journalist frogs is too young and simple to run a long distance efficiently. As a result, it takes L 2 Time for them to run through a path of length L. In addition, passing message requires P time for checking the message carefully, because all mistake in the message would Make the Elder become extremely angry.
Now is excited to receive the task to calculate the maximum time of sending a message from one of these cities to the Capital.
Inputthe first line of input contains an integer t, the number of test cases. T test cases follow. For each test case, the first line there is integers N (n≤100000) and P (p≤1000000). In the next N-1 lines, the i-th line describes the I-th road, a line with three integers u,v,w denotes an edge between the U-th City and V-th city with length W (w≤100).
Outputfor each case, output the maximum time.
Sample Input
36 101 2 42 3 51 4 34 5 35 6 36 301 2 42 3 51 4 34 5 35 6 36 501 2 42 3 51 4 34 5 35 6 3
Sample Output
517581Hint
Wrote the Tree divide and conquer double log of the practice, was HDU card off.
Would like to see how others write, the results found that there is only a violent retrospective on the internet
A chrysanthemum diagram, and then the sub-node particularly good words can be stuck out. It just doesn't seem to be the data.
Let's talk about the idea of tree splitting.
Len[i] Represents the length from 1 to I
Naive Equation F[i]=max (f[j]+ (Len[j]-len[i]) ^2) +p
And then assuming J is above K, J is better than K.
(f[j]+ (Len[j]-len[i]) ^2) +p< (f[k]+ (Len[k]-len[i]) ^2) +p
The slope equation is obtained by moving the term
((F[k]+len[k]*len[k])-(f[j]+len[j]*len[j])/((LEN[K]-LEN[J]) * *) >len[i]
Monotonic on the right
The maintenance slope can be reduced monotonically
The concrete way is, for a certain center of gravity, we first divide the center of gravity above, then divide the center of gravity below.
When we divide, we jump from the center of gravity to the current root and maintain a convex hull in this chain.
The points below the center of gravity are sorted by the length of the center of gravity, and then from the top of the convex hull to the best, from the first team.
Lose a code first, the PAT should be no problem, but the HDU will be T. The scene is supposed to be over.
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------
Update: Card Kathang After the election of no one review no one to rob the evaluation of resources, the time to pay, too
Original code:
#include <cstdio> #include <string> #include <cstring> #include <iostream> #include < algorithm>using namespace Std;inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} struct Line{int s,t;int x;int next;bool flag;} A[200001];int head[100001];int edge;inline void Add (int s,int t,int x) {a[edge].next=head[s]; head[s]=edge;a[edge].s=s; A[edge].t=t;a[edge].x=x;a[edge].flag=true;} Long long Len[100001];long long f[100001];int fa[100001];inline BOOL cmp (int x,int y) {return len[x]>len[y];} inline void getl (int d) {int i;for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t;if (T!=fa[d]) {fa[t]=d;len[t]=len[d]+a[i]. X;getl (t);}}} int mini,minx;int son[100001];bool v[100001];inline void Find (int d,int s) {son[d]=0;int i;int tmp=0;for (i=head[d];i!=0; I=a[i].next) {int t=a[i].t;if (A[i].flag&&t!=fa[d]) {find (t,s); son[d]+= (son[t]+1); Tmp=max (TMP,son[t]+1);}} int Mx=max (tmp,s-tmp-1); if (Mx<minx) {Minx=mx;mini=d;}} int Sx[100001],dis[100001],px[100001];int p;inline double getk (int k,int j) {return (double) ((F[k]+len[k]*len[k])-(f[j ]+LEN[J]*LEN[J])/double (Len[k]-len[j])/double (2);} int ps;inline void gets (int d) {int i;for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t;if (A[i].flag&&t!=fa[d]) { int t=a[i].t; ps++; px[ps]=t; Gets (t); }}}int q[100001];inline void solve (int d,int Size,int ZX) {if (size==1) return; if (size==2) {if (Len[zx]>len[d]) f[zx]= Min (f[zx],f[d]+ (len[zx]-len[d]) * (Len[zx]-len[d]) +p); return;} int I;int ttx=son[zx];son[d]-=son[zx];for (i=head[zx];i!=0;i=a[i].next) a[i].flag=false;minx=2100000000;mini=0; Find (d,son[d]+1); solve (D,son[d]+1,mini); for (I=head[zx];i!=0;i=a[i].next) a[i].flag=true;//ps=1;//px[ps]=zx;ps=0 , gets (ZX), sort (px+1,px+1+ps,cmp), int dx=zx;int l=1,r=0,lt=1;while (Dx!=fa[d]) {while (L<R&&GETK (q[r-1],q [R]) <GETK (Q[R],DX)) r--; R++;Q[R]=DX;DX=FA[DX];} for (i=1;i<=ps;i++) {while (l<r&&amP;GETK (q[l],q[l+1]) >len[px[i]) l++;if (px[i]==1) continue;f[px[i]]=f[q[l]]+ (Len[px[i]]-len[q[l]]) * (Len[px[i]] -LEN[Q[L]]) +p;} Find (zx,ttx+1); for (i=head[zx];i!=0;i=a[i].next) {int t=a[i].t;if (T==FA[ZX]) Continue;minx=2100000000;mini=0;find ( T,SON[T]+1); solve (T,son[t]+1,mini);}} int main () {//freopen ("i.in", "R", stdin),//freopen ("I.out", "w", stdout), int t;//scanf ("%d", &t); T=read (); while (t>0) {t--;int n;n=read (); P=read ();//SCANF ("%d%d", &n,&p); int I;int S,t,x;memset (head,0,sizeof (head)); Edge=0;for (i=1;i<=n-1;i++) {S=read (); T=read (); X=read ();//SCANF ("%d%d%d", &s,&t,&x); Edge++;add (s,t,x); Edge++;add (t,s,x);} memset (len,0,sizeof (len)); memset (fa,0,sizeof (FA)); Getl (1); Memset (F,127/3,sizeof (f)); f[1]=0;minx=2100000000; mini=0; Find (1,n); Solve (1,n,mini); Long long ans=0;//for (i=1;i<=n;i++)//printf ("%d:%lld\n", I,f[i]); for (i=2;i<=n;i++) Ans=max ( Ans,f[i]);p rintf ("%lld\n", ans-p); }return 0;}
AC Code:
#include <cstdio> #include <string> #include <cstring> #include <iostream> #include < algorithm>using namespace Std;/*inline int max (int x,int y) {if (x>y) return X;return y; inline int min (int x,int y) {if (x<y) return X;return y;} */inline Long Long max (long long X,long long y) {if (x>y) return X;return y; Inline Long long min (Long long X,long long y) {if (x<y) return X;return y;} inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} struct Line{int s,t;int x;int next;bool flag;} A[200001];int head[100001];int edge;inline void Add (int s,int t,int x) {a[edge].next=head[s]; head[s]=edge;a[edge].s=s; A[edge].t=t;a[edge].x=x;a[edge].flag=true;} Long long Lenx[100001];long long len[100001];//int len[100001];//int f[100001];long long f[100001];int fa[100001]; inline BOOL cmp (int x,int y) {return len[x]>len[y];} inline void Getl (intd) {int i;for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t;if (T!=fa[d]) {fa[t]=d;len[t]=len[d]+a[i].x;getl (t);}}} int mini,minx;int son[100001];bool v[100001];inline void Find (int d,int s) {son[d]=0;int i;int tmp=0;for (i=head[d];i!=0; I=a[i].next) {int t=a[i].t;if (A[i].flag&&t!=fa[d]) {find (t,s); son[d]+= (son[t]+1); Tmp=max (tmp,son[t]+1);}} int Mx=max (tmp,s-tmp-1); if (Mx<minx) {Minx=mx;mini=d;}} int Sx[100001],dis[100001],px[100001];int p;/*inline double getk (int k,int j) {return (double) ((F[k]+len[k]*len[k])-(f [J]+len[j]*len[j])/double (Len[k]-len[j])/double (2);} */inline bool Check (int k1,int j1,int k2,int j2) {return ((F[k1]+lenx[k1])-(f[j1]+lenx[j1])) * (Len[k2]-len[j2]) < ((f[ K2]+LENX[K2])-(F[J2]+LENX[J2])) * (Len[k1]-len[j1]);} inline int Checkk (int k,int j,int lenxt) {return ((F[k]+lenx[k])-(f[j]+lenx[j])) >lenxt*2* (Len[k]-len[j]);} int ps;inline void gets (int d) {int i;for (i=head[d];i!=0;i=a[i].next) {int t=a[i].t;if (A[i].flag&&t!=fa[d]) {PS ++; px[ps]=t; Gets (t); }}}int q[100001];inline void Solve (int d,int Size,int ZX) {if (size==1) return; if (size==2) {if (Len[zx]>len[d]) f[zx]=min (f[zx],f[d]+ (Len[zx]-len[d]) * (Len[zx]-len[d]) +p); return;} int I;int ttx=son[zx];son[d]-=son[zx];for (i=head[zx];i!=0;i=a[i].next) a[i].flag=false;minx=2100000000;mini=0; Find (d,son[d]+1); solve (D,son[d]+1,mini); for (I=head[zx];i!=0;i=a[i].next) a[i].flag=true;//ps=1;//px[ps]=zx;ps=0 , gets (ZX), sort (px+1,px+1+ps,cmp), int dx=zx;int l=1,r=0,lt=1;while (dx!=fa[d]) {//while (L<R&&GETK (q[r-1) , Q[r]) <GETK (Q[R],DX)) while (L<r&&check (Q[R-1],Q[R],Q[R],DX)) r--; R++;Q[R]=DX;DX=FA[DX];} for (i=1;i<=ps;i++) {//while (L<R&&GETK (q[l],q[l+1]) >len[px[i]) while (L<r&&checkk (q[l ],q[l+1],len[px[i]) l++;if (px[i]==1) continue;f[px[i]]=min (f[px[i]],f[q[l]]+ (Len[px[i]]-len[q[l]]) * (Len[px[i]] -LEN[Q[L]]) +p);} Find (zx,ttx+1); for (i=head[zx];i!=0;i=a[i].next) {int t=a[i].t;if (T==FA[ZX]) continue;minx=2100000000;mini=0; Find (t,son[t]+1); solve (T,son[t]+1,mini);}} int main () {Freopen ("I.in", "R", stdin),//freopen ("I.out", "w", stdout), int t;//scanf ("%d", &t); T=read (); while (t>0) {t--;int n;n=read (); P=read ();//SCANF ("%d%d", &n,&p), if (n==1) {printf ("0\n"); continue;} int I;int S,t,x;memset (head,0,sizeof (head)), Edge=0;for (i=1;i<=n-1;i++) {s=read (); T=read (); X=read ();//SCANF ("%d %d%d ", &s,&t,&x); Edge++;add (s,t,x); Edge++;add (t,s,x);} memset (fa,0,sizeof (FA)); Getl (1); for (i=1;i<=n;i++) lenx[i]= (Long Long) len[i]* (Len[i];memset, sizeof (f)); f[1]=0;minx=2100000000; mini=0; Find (1,n); Solve (1,n,mini); Long long ans=0;//for (i=1;i<=n;i++)//printf ("%d:%lld\n", I,f[i]); for (i=2;i<=n;i++) Ans=max ( Ans,f[i]);p rintf ("%lld\n", ans-p); }return 0;}
Hdu 5956 the Elder 2016acm/icpc Shenyang Division live Race I