zoukankan      html  css  js  c++  java
  • [ HDU

    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 */





  • 相关阅读:
    20140322 卡迪夫城VS利物浦,拔出重剑,有惊无险
    20140316 曼联VS利物浦,罗杰斯的小九九,当4312对上4231
    『看球笔记』20140217 红军足总杯遭枪手2-1淘汰 ,胜负手在哪?
    『看球笔记』20140208利物浦VS阿森纳,十字重剑与蜜蜂飞舞
    『看球笔记』20131230切尔西vs利物浦,赛后复盘聊聊球
    Full scan vs index 执行计划的实验
    『看球笔记』利物浦0:1南安普顿,罗杰斯,你的牌技太差了
    无题
    开源啦!安卓版起床资讯闹钟,丰富大家早晨起床的android应用,评论过十就开了。
    开源啦!Android版语音天气闹钟
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11145829.html
Copyright © 2011-2022 走看看