JZOJ 5196. 【NOIP2017提高组模拟7.3】B

时间:2022-12-17 14:31:41

Description

JZOJ 5196. 【NOIP2017提高组模拟7.3】B
 

Input

JZOJ 5196. 【NOIP2017提高组模拟7.3】B

Output

JZOJ 5196. 【NOIP2017提高组模拟7.3】B
 

Sample Input

5 10 40
2 4 80
2 3 57
1 2 16
2 5 49

Sample Output

16
 
做法:点分治,emmmm,比较接近模板了。
代码如下:
JZOJ 5196. 【NOIP2017提高组模拟7.3】BJZOJ 5196. 【NOIP2017提高组模拟7.3】B
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #define N 300007
  6 #define LL long long
  7 using namespace std;
  8 LL n, S, E, ls[N], tot, Ma[N], Size[N], sum, root, Len ;
  9 LL d[N], ans;
 10 bool v[N];
 11 struct edge
 12 {
 13     LL to, next, w;
 14 }e[N * 2];
 15 struct arr
 16 {
 17     LL dis;
 18     int fa;
 19 }a[N];
 20 
 21 inline void Add(int x, int y, int w)
 22 {
 23     e[++tot].to = y;
 24     e[tot].w = w;
 25     e[tot].next = ls[x];
 26     ls[x] = tot;
 27 }
 28 
 29 inline void Getroot(int x, int fa)
 30 {
 31     Ma[x] = 0, Size[x] = 1;
 32     for (int i = ls[x]; i; i = e[i].next)
 33     {
 34         int    visit = e[i].to;
 35         if (v[visit] || visit == fa)    continue;
 36         Getroot(visit, x);
 37         Size[x] += Size[visit];
 38         Ma[x] = max(Size[visit], Ma[x]);
 39     }
 40     Ma[x] = max(Ma[x], sum - Size[x]);
 41     if (Ma[x] < Ma[root]) root = x;
 42 }
 43 
 44 inline void Getval(int x, int fa, int zs)
 45 {
 46     a[++Len].dis = d[x];
 47     a[Len].fa = zs;
 48     for (int i = ls[x]; i; i = e[i].next)
 49     {
 50         int    visit = e[i].to;
 51         if (v[visit] || visit == fa)    continue;
 52         d[visit] = d[x] + e[i].w;
 53         if (!zs)    Getval(visit, x, visit);
 54         else Getval(visit, x, zs);    
 55     }
 56 }
 57 
 58 int cmp(arr x, arr y)
 59 {
 60     return x.dis < y.dis; 
 61 }
 62 
 63 inline LL Acu(int x)
 64 {
 65     Len = 0, d[x] = 0;
 66     Getval(x, 0, 0);
 67     sort(a + 1, a + Len + 1, cmp);
 68     int l = 1, r = Len;
 69     for (; l < r; )
 70     {
 71         if (a[l].fa == a[r].fa)
 72         {
 73             if (a[l].dis + a[r - 1].dis < S) l++;
 74             else r--;
 75         }
 76         else
 77         {
 78             if (a[l].dis + a[r].dis >= S)
 79             {
 80                 ans = min(ans,(LL)(a[l].dis + a[r].dis));
 81                 r--;
 82             }
 83             else l++;
 84         }
 85     }
 86 }
 87 
 88 inline void work(int x)
 89 {
 90     Acu(x);
 91     v[x] = 1;
 92     for (int i = ls[x]; i; i = e[i].next)
 93     {
 94         int    visit = e[i].to;
 95         if (v[visit]) continue;
 96         sum = Size[visit];
 97         root = 0;
 98         Getroot(visit, 0);
 99         work(root);
100     }
101 }
102 
103 int main()
104 {
105     scanf("%d%d%d", &n, &S, &E);
106     memset(v, 0, sizeof(v));
107     memset(ls, 0, sizeof(ls));
108     for (int i = 1; i <= n - 1; i++)
109     {
110         int u, v, w;
111         scanf("%d%d%d", &u, &v, &w);
112         Add(u, v, w);
113         Add(v, u, w);
114     }
115     ans = 0x3f3f3f3f;
116     sum = n;
117     Ma[0] = 0x3f3f3f3f;
118     Getroot(1, 0);
119     work(root);
120     if (ans > E)    printf("-1");
121     else printf("%lld", ans);
122 }
View Code