Codevs 2756 树上的路径

2756 树上的路径

 时间限制: 3 s     空间限制: 128000 KB     题目等级 : 大师 Master
 
 
题目描述 Description

给出一棵树,求出最小的k,使得,且在树中存在路径P,使得k>= S 且 k <=E. (k为路径P上的边的权值和)

输入描述 Input Description

第一行给出N,S,E,N代表树的点数,S,E如题目描述一致

下面N-1行给出这棵树的相邻两个节点的边及其权值W

输出描述 Output Description

输出一个整数k,表示存在路径P,并且路径上的权值和 K>=S , k<=E,若无解输出-1

样例输入 Sample Input

5 10 40

2 4 80

2 3 57

1 2 16

2 5 49

样例输出 Sample Output

16

数据范围及提示 Data Size & Hint

边权W<=10000,

保证答案在int(longint)范围内,且|E-S|<=50,

树上点的个数N<=30000

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define N 30009
 6 using namespace std;
 7 int n,A,B,K,la,head[N],next[N<<1],ans=2*1e9,size[N];
 8 int dep[N],maxson[N],root,tot,lls,num,ls[N];
 9 bool v[N];
10 struct node
11 {
12     int fr,to,len;
13 }a[N<<1];
14 void addedge(int x,int y,int z)
15 {
16     a[++la].fr=x,a[la].to=y,a[la].len=z;
17     next[la]=head[x],head[x]=la;
18 }
19 void get_root(int x,int from)
20 {
21     size[x]=1;
22     maxson[x]=0;
23     for(int i=head[x];i;i=next[i])
24         if (!v[ a[i].to ]&&a[i].to!=from)
25             {
26                 get_root(a[i].to,x);
27                 size[x]+=size[ a[i].to ];
28                 maxson[x]=max(maxson[x],size[ a[i].to ]);
29             }
30     maxson[x]=max( maxson[x],tot-size[x] );
31     if (!root||maxson[x]<maxson[root]) root=x;
32 
33 }
34 void get_dep(int x,int from)
35 {
36     for (int i=head[x];i;i=next[i])
37         if (!v[ a[i].to ]&&a[i].to!=from)
38             {
39                 ls[++lls]=dep[ a[i].to ]=dep[x]+a[i].len;
40                 get_dep(a[i].to,x);
41 
42             }
43 }
44 int get_num(int x,int jian)
45 {
46     int i,j,k,rt=0;
47     ls[ lls=1 ]=dep[x]=jian;
48     get_dep(x,0);
49     
50     sort(ls+1,ls+lls+1);
51     for (i=1,j=lls;i<=lls;i++)
52         {
53             while (j>1&&ls[i]+ls[j]>K) j--;
54             if (j>i)rt+=j-i;
55         }
56     return rt;
57 }
58 void divide(int x)
59 {
60     num+=get_num(x,0);
61     v[x]=1;
62     for (int i=head[x];i;i=next[i])
63         if (!v[ a[i].to ]) 
64             {
65                 num-=get_num(a[i].to,a[i].len);
66                 tot=size[ a[i].to ];
67                 root=0,get_root(a[i].to,0);
68                 divide( root );
69             }
70 }
71 int main()
72 {
73     int i,j,k,x,y,z,last;
74     scanf("%d%d%d",&n,&A,&B); 
75     for(i=1;i<n;i++)
76     {
77         scanf("%d%d%d",&x,&y,&z);
78         addedge(x,y,z),addedge(y,x,z);
79     }
80     last=1e9;
81     for(K=A-1;K<=B;K++)
82     {
83         num=0;
84         memset(v,0,sizeof(v));
85         tot=n,root=0;
86         get_root(1,0);
87         divide(root);
88         if(num>last)
89         {
90             printf("%d
",K);
91             return 0;
92         }
93         last=num;
94     }
95     printf("-1
");
96 }

 备注:引用自Codevs 题解

原文地址:https://www.cnblogs.com/suishiguang/p/6172038.html