• [WC 2010]重建计划


    Description

    Input

    第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号

    Output

    输出最大平均估值,保留三位小数

    Sample Input

    4
    2 3
    1 2 1
    1 3 2
    1 4 3

    Sample Output

    2.500

    HINT

    N<=100000,1<=L<=U<=N-1,Vi<=1000000

    题解

    本机实测是可以 $A$ 的,但爆炸 $oj$ 的老爷机实在不可恭维,并且还多加了一组更为毒瘤的数据...

    加了所有的常数优化都过不了,气愤的不想写题解,直接丢链接。

    ->题解在这里<-

      1 //It is made by Awson on 2018.1.5
      2 #include <set>
      3 #include <map>
      4 #include <cmath>
      5 #include <ctime>
      6 #include <queue>
      7 #include <stack>
      8 #include <cstdio>
      9 #include <string>
     10 #include <vector>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <algorithm>
     15 #define LL long long
     16 #define RE register
     17 #define lowbit(x) ((x)&(-(x)))
     18 #define Max(a, b) ((a) > (b) ? (a) : (b))
     19 #define Min(a, b) ((a) < (b) ? (a) : (b))
     20 using namespace std;
     21 const int N = 100000;
     22 const int INF = ~0u>>1;
     23 const double eps = 4e-4;
     24 void read(int &x) {
     25     char ch; x = 0;
     26     ch = getchar(); while (ch < '0' || ch > '9') ch = getchar();
     27     while (ch >= '0' && ch <= '9') x = (x<<1)+(x<<3)+ch-48, ch = getchar();
     28 }
     29 
     30 int n, L, U, a, b, c;
     31 struct tt {
     32     int to, next;
     33     double cost, c;
     34 }edge[(N<<1)+5];
     35 int path[N+5], top;
     36 int root[N+5];
     37 void add(int u, int v, double c) {
     38     edge[++top].to = v;
     39     edge[top].cost = edge[top].c = c;
     40     edge[top].next = path[u];
     41     path[u] = top;
     42 }
     43 
     44 namespace PRE {
     45     int size[N+5], mx[N+5], minsize, rt, vis[N+5], tot;
     46     void get_root(int o, int pa, int fa) {
     47     mx[o] = Max(mx[o], size[pa]-size[o]);
     48     if (mx[o] < minsize) minsize = mx[o], rt = o;
     49     for (RE int i = path[o]; i; i = edge[i].next)
     50         if (edge[i].to != fa && !vis[edge[i].to]) get_root(edge[i].to, pa, o);
     51     }
     52     void get_size(int o, int fa) {
     53     size[o] = 1, mx[o] = 0;
     54     for (RE int i = path[o]; i; i = edge[i].next)
     55         if (edge[i].to != fa && !vis[edge[i].to]) {
     56         get_size(edge[i].to, o);
     57         size[o] += size[edge[i].to];
     58         if (size[edge[i].to] > mx[o]) mx[o] = size[edge[i].to];
     59         }
     60     }
     61     void work(int o) {
     62     minsize = INF;
     63     get_size(o, 0), get_root(o, o, 0);
     64     root[++tot] = rt, vis[rt] = 1;
     65     for (RE int i = path[rt]; i; i = edge[i].next)
     66         if (!vis[edge[i].to]) work(edge[i].to);
     67     }
     68     void main() {work(1); }
     69 }
     70 
     71 double mx[N+5], dist[N+5];
     72 int q[N+5], vis[N+5], dep[N+5], dq[N+5], fa[N+5];
     73 
     74 bool cal(int o) {
     75     int maxdep = 0;
     76     for (RE int I = path[o]; I; I = edge[I].next)
     77     if (!vis[edge[I].to]) {
     78         int head = 0, tail = 0; q[tail] = edge[I].to, dep[q[0]] = 1, dist[q[0]] = edge[I].cost, fa[q[0]] = o, ++tail; 
     79         while (head < tail) {
     80         int now = q[head]; ++head;
     81         for (RE int i = path[now]; i; i = edge[i].next)
     82             if (fa[now] != edge[i].to && !vis[edge[i].to]) {
     83             q[tail] = edge[i].to, ++tail;
     84             dep[edge[i].to] = dep[now]+1;
     85             dist[edge[i].to] = dist[now]+edge[i].cost;
     86             fa[edge[i].to] = now;
     87             }
     88         }
     89         int head1 = 0, tail1 = 0, now = maxdep; 
     90         for (RE int i = 0; i < tail; ++i) {
     91         int x = q[i];
     92         while (dep[x]+now >= L && now >= 0) {
     93             while (head1 < tail1 && mx[dq[tail1-1]] < mx[now]) --tail1;
     94             dq[tail1] = now; ++tail1, --now;
     95         }
     96         while (head1 < tail1 && dq[head1]+dep[x] > U) ++head1;
     97         if (head1 < tail1 && dist[x]+mx[dq[head1]] >= 0) return true;
     98         }
     99         maxdep = Max(maxdep, dep[q[tail-1]]);
    100         for (RE int i = 0; i < tail; ++i) {
    101         fa[q[i]] = 0; if (mx[dep[q[i]]] < dist[q[i]]) mx[dep[q[i]]] = dist[q[i]];
    102         }
    103     }
    104     for (RE int i = 1; i <= maxdep; i++) mx[i] = -INF;
    105     return false;
    106 }
    107 bool solve(int o, int &num) {
    108     vis[o] = 1;
    109     if (cal(o)) return true;
    110     for (RE int i = path[o]; i ;i = edge[i].next)
    111     if (!vis[edge[i].to]) {
    112         ++num; if (solve(root[num], num)) return true;
    113     }
    114     return false;
    115 }
    116 void pre(double key) {
    117     for (RE int i = 1; i <= n; ++i) {
    118     edge[i<<1].cost = edge[i<<1].c-key, edge[(i<<1)-1].cost = edge[(i<<1)-1].c-key;
    119     vis[i] = 0, mx[i] = -INF;
    120     }
    121 }
    122 void work() {
    123     read(n), read(L), read(U);
    124     double L = 0, R = 0;
    125     for (RE int i = 1; i < n; ++i) {
    126     read(a), read(b), read(c);
    127     add(a, b, c), add(b, a, c); if (R < c) R = c;
    128     }
    129     PRE::main();
    130     while (R-L > eps) {
    131     double mid = (L+R)/2.; pre(mid);
    132     int tot = 1;
    133     if (solve(root[1], tot)) L = mid;
    134     else R = mid;
    135     }
    136     printf("%.3lf
    ", (L+R)/2.);
    137 }
    138 int main() {
    139     work();
    140     return 0;
    141 }
  • 相关阅读:
    MySQL 可重复读,差点就让我背上了一个 P0 事故
    Thread.sleep(0) 有什么用
    你不会还在用这8个错误的SQL写法吧?
    Spring事务失效的 8 大原因
    我说 SELECT COUNT(*) 会造成全表扫描,面试官让我回去等通知
    这么写参数校验(Validator)就不会被劝退了
    HyperLedger Fabric 1.4 基础环境搭建(7)
    HyperLedger Fabric 1.4 简介(6.1)
    HyperLedger Fabric 1.4 关键技术(6.4)
    HyperLedger Fabric 1.4 交易流程(6.3)
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/8206689.html
Copyright © 2020-2023  润新知