标签:let distance input continue eve cas imu ane const
InputThe first line of input contains an integer t, the number of test cases. t test cases follow. For each test case, in the first line there are two 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
3
6 10
1 2 4
2 3 5
1 4 3
4 5 3
5 6 3
6 30
1 2 4
2 3 5
1 4 3
4 5 3
5 6 3
6 50
1 2 4
2 3 5
1 4 3
4 5 3
5 6 3
Sample Output
51
75
81
Hint
In the second case, the best transportation time is: • The 2-th city: 16 = 4^2 • The 3-th city: 72 = 4^2 + 30 + 5^2 • The 4-th city: 9 = 3^2 • The 5-th city: 36 = (3 + 3)^2 • The 6-th city: 75 = (3 + 3)^2 +30 + 3^2 Consequently, the news in the 6-th city requires most time to reach the capital.
solution:
写出转移方程,是一个树上斜率优化的形式
二分找最优的转移点
二分找当前点插入的位置
注意点是当最优的转移点是0时,不能加P
CODE:
1 #include"bits/stdc++.h"
2 using namespace std ;
3 typedef long long ll;
4 #define int long long
5 struct aa
6 {
7 int so;
8 ll w;
9 };
10 const int N = 100010;
11 vector<aa> v[N];
12 int n,P;
13 ll f[N];
14 int d[N];
15 int que[N];
16
17 double Y(int x)
18 {
19 return f[x] + d[x]*d[x] + P*(x!=0) ;
20 }
21
22 double X(int x)
23 {
24 return d[x];
25 };
26
27 double slope(int a,int b)
28 {
29 return (Y(b)-Y(a))/(X(b)-X(a));
30 }
31
32 inline int find1(int x,int pos)
33 {
34 int l=0,r=pos-1,ans=pos;
35 while(l<=r)
36 {
37 int mid = l+r>>1;
38 if(slope(que[mid],que[mid+1]) >=(double)2*d[x])
39 ans=mid,r=mid-1;
40 else
41 l=mid+1;
42 }
43 return ans;
44 }
45
46 int find2(int x,int pos)
47 {
48 int l=0,r=pos-1,ans=pos+1;
49 while(l<=r)
50 {
51 int mid = l+r>>1;
52 if(slope(que[mid],que[mid+1]) <= slope(que[mid],x))
53 l=mid+1;
54 else
55 ans=mid+1,r=mid-1;
56 }
57 return ans;
58 }
59
60 void dfs(int x,int pos,int fa)
61 {
62 if(x==1)
63 {
64
65 for(auto i:v[x])
66 {
67 if(i.so==fa)
68 continue;
69 d[i.so] = d[x] + i.w;
70 dfs(i.so,0,x);
71 }
72 return ;
73 }
74
75 int t=find1(x,pos);
76 int k=que[t];
77
78 f[x] = f[k]+(d[x]-d[k])*(d[x]-d[k]) + P;
79 if(k==0)
80 f[x]-=P;
81
82 int t2=find2(x,pos);
83 int t3=que[t2];
84 que[t2]=x;
85
86 for(auto i:v[x])
87 {
88 if(i.so==fa)
89 continue;
90 d[i.so] = d[x] + i.w;
91 dfs(i.so,t2,x);
92 }
93
94 que[t2]=t3;
95 }
96 signed main()
97 {
98 int T;
99 for(cin>>T; T; T--)
100 {
101 cin>>n>>P;
102 for(int i=1; i<n; i++)
103 {
104 int l,r,z;
105 scanf("%lld %lld %lld",&l,&r,&z);
106 v[l].push_back({r,z});
107 v[r].push_back({l,z});
108 }
109 dfs(1,0,0);
110 for(int i=1; i<=n; i++)
111 v[i].clear();
112
113 int mx=0;
114 for(int i=2; i<=n; i++)
115 mx=max(mx,f[i]);
116 cout<<mx<<endl;
117 }
118 }
119
120 /*
121
122 11
123 5 1
124 1 2 100
125 2 3 100
126 3 4 100
127 4 5 100
128
129
130 */
[ HDU - 5956 ] The Elder (树上斜率优化)
标签:let distance input continue eve cas imu ane const
原文地址:https://www.cnblogs.com/zhangbuang/p/11145829.html