zoukankan      html  css  js  c++  java
  • Qin Shi Huang's National Road System HDU

    原题链接

    • 题意:遍历每个非关键边,预处理出来两个 (MST) 中的点到最近公共祖先的最长的边的距离,然后就是 (frac{cnt}{sum - Max_{i,j}}) 枚举 (i,j) 即可,简直就和求最小生成树的过程一模一样。
    • 代码:
    #include <cstring>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    const int N = 1111;
    const int M = 2 * N * N;
    int cnt = 0;
    double sum = 0;
    int h[N], to[M], ne[M], idx;
    double W[M];
    int dep[N];
    int f[N][20];
    double g[N][20];
    void add(int u, int v ,double w) {
        ne[idx] =h[u], to[idx] = v, W[idx]  =w, h[u] = idx++;
    }
    void dfs(int u, int fa) {
        if (fa == -1)dep[u] = 1;
        else dep[u] = dep[fa] + 1;
        for (int i = 1; i <= 13; i ++) {
            f[u][i] = f[f[u][i-1]][i-1];
            g[u][i] = max(g[u][i-1],g[f[u][i-1]][i-1]);
        }
        for (int i = h[u]; i!= -1; i = ne[i]) {
            int v = to[i];
            if (dep[v] == 0) {
                f[v][0] = u;
                g[v][0] = W[i];
                dfs(v, u);
            }
        }
        
    }
    struct node {
        double x, y;
        int cnt;
    }p[N];
    struct edge {
        int u, v;double w;
        int cnt;
    }e[M];
    bool cmp(edge a, edge b){return a.w < b.w;}
    int fa[N];
    int Find(int x){return fa[x] == x?x:fa[x] = Find(fa[x]);}
    double dis(node a, node b) {
        return sqrt((a.x- b.x)*(a.x-b.x) + (a.y - b.y) * (a.y - b.y));
    }
    void un(int i) {
        int fx = Find(e[i].u);
        int fy = Find(e[i].v);
        if (fx == fy)return;
        fa[fx] = fy;
        add(e[i].u, e[i].v, e[i].w);
        add(e[i].v, e[i].u, e[i].w);
        sum += e[i].w;
    }
    double lca(int u, int v) {
        if (dep[u] < dep[v])swap(u, v);
        double ret = -1;
        for (int i = 14; i >= 0; i--) {
            if (dep[f[u][i]] >= dep[v]) {
                ret = max(ret, g[u][i]);
                u = f[u][i];
            }
        }
        if (u == v)return ret;
        for (int i = 14; i >= 0; i--) {
            if (f[u][i] != f[v][i]) {
                ret = max(ret, max(g[u][i], g[v][i]));
                u = f[u][i], v = f[v][i];
            }
        }
        ret = max(ret, max(g[u][0], g[v][0]));
        return ret;
    }
    void solve() {
        int n;scanf("%d", &n);
        for (int i = 1; i <= n; i ++) {
            scanf("%lf%lf%d", &p[i].x, &p[i].y,&p[i].cnt);
            fa[i] = i;
        }
        int m = 0;cnt = 0;
        sum = 0;
        double ans = -1;
        memset(h, -1, sizeof h);idx = 0;
        memset(dep, 0, sizeof dep);
        for (int i = 1; i <= n; i ++) {
            for (int j = i + 1; j <= n; j ++) {
                e[++m] = {i, j, dis(p[i], p[j])};
            }
        }
        sort(e + 1, e + 1 +  m, cmp);
        for (int i = 1; i <= m; i ++) {
            un(i);
        }
        dfs(1, -1);
        for (int i = 1; i <= n; i ++) {
            for (int j = i + 1; j <=n; j ++) {
                ans = max(ans,(double)( p[i].cnt + p[j].cnt*1.0 )/(sum - lca(i, j) ) );
            }
        }
        printf("%.2lf
    ", ans);
    }
    signed main() {
        int t;scanf("%d", &t);
        while (t--) {
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    CodeForces
    Codeforces 1523D Love-Hate(随机化算法,sos dp)
    CodeForces
    讲题泛做
    CF vp 新题乱做
    10.11 牛客
    10.6 牛客
    10.4 牛客
    10.9 模拟考试 题解报告
    9.18 校内模拟赛 题解报告
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14635770.html
Copyright © 2011-2022 走看看