[ HDU - 5956 ] The Elder (树上斜率优化)

Once upon a time, in the mystical continent, there is a frog kingdom, ruled by the oldest frog, the Elder. The kingdom consists of N cities, numbered from east to west. The 1-th city, which is located to the east of others, is the capital. Each city, except the capital, links none or several cities to the west, and exactly one city to the east. 
There are some significant news happening in some cities every day. The Elder wants to know them as soon as possible. So, that is the job of journalist frogs, who run faster than any other frog. Once some tremendous news happen in a city, the journalist in that city would take the message and run to the capital. Once it reach another city, it can either continue running, or stop at that city and let another journalist to transport. The journalist frogs are too young and simple to run a long distance efficiently. As a result, it takes L2L2 time for them to run through a path of length L. In addition, passing message requires P time for checking the message carefully, because any mistake in the message would make the Elder become extremely angry. 
Now you are 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, 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 */

 






 

转载于:https://www.cnblogs.com/zhangbuang/p/11145829.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值