码迷,mamicode.com
首页 > Windows程序 > 详细

CS academy Growing Trees【模板】DP求树的直径

时间:2018-10-31 15:44:57      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:pac   code   mem   inline   long   png   nbsp   namespace   mes   

技术分享图片

【题意概述】

  给出一棵树,树上的边有两个值a和b,你可以在[0,limit]范围内选择一个整数delta,树上的边的权值为a+b*delta,现在问当delta为多少的时候树的直径最小、最小直径是多少。

【题解】

  每条边的边权都是一次函数,那么直径是单峰函数。单峰函数求最小值我们可以用三分法。

  注意边权可能为负数,求直径时要用DP,而不能用dfs到最远点、再从最远点dfs到它的最远点的方法。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 #define rg register
 6 #define N 500010
 7 using namespace std;
 8 int n,m,tot,del,l,r,last[N];
 9 LL ans=3e18,mx,dis[N][2];
10 struct edge{
11     int to,pre; LL w;
12 }e[N<<1];
13 struct rec{
14     int u,v,a,b;
15 }re[N];
16 inline int read(){
17     int k=0,f=1; char c=getchar();
18     while(c<0||c>9)c==-&&(f=-1),c=getchar();
19     while(0<=c&&c<=9)k=k*10+c-0,c=getchar();
20     return k*f;
21 } 
22 void dfs(int x,int fa){
23     for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa){
24         dfs(to,x); LL tmp=dis[to][0]+e[i].w;
25         if(tmp>=dis[x][0]){
26             dis[x][1]=dis[x][0],dis[x][0]=tmp;
27         }
28         else
29             if(tmp>dis[x][1]) dis[x][1]=tmp;
30     }
31     mx=max(mx,max(dis[x][0],dis[x][0]+dis[x][1]));
32 }
33 inline LL calc(int x){
34     memset(last,0,sizeof(last)); tot=0;
35     for(rg int i=1;i<n;i++){
36         int u=re[i].u,v=re[i].v; LL w=re[i].a+re[i].b*x;
37         e[++tot]=(edge){u,last[v],w}; last[v]=tot;
38         e[++tot]=(edge){v,last[u],w}; last[u]=tot;
39     }
40     memset(dis,0,sizeof(dis)); mx=0;
41     dfs(1,0);
42     return mx;
43 }
44 signed main(){
45     n=read(); l=-1; r=read();
46     for(rg int i=1;i<n;i++){
47         re[i].u=read(); re[i].v=read(); re[i].a=read(); re[i].b=read();
48     }
49     while(l+1<r){
50         int mid1=(l+r)>>1,mid2=mid1+1;
51         if(calc(mid1)<=calc(mid2)) r=mid1;
52         else l=mid1;
53     }
54     printf("%d\n%lld\n",r,calc(r));
55     return 0;
56 }

 

CS academy Growing Trees【模板】DP求树的直径

标签:pac   code   mem   inline   long   png   nbsp   namespace   mes   

原文地址:https://www.cnblogs.com/DriverLao/p/9883009.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!