`
Simone_chou
  • 浏览: 192592 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Qin Shi Huang's National Road System(最小生成树 + LCA)

    博客分类:
  • HDOJ
 
阅读更多

Qin Shi Huang's National Road System

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3750    Accepted Submission(s): 1305


Problem Description
During the Warring States Period of ancient China(476 BC to 221 BC), there were seven kingdoms in China ---- they were Qi, Chu, Yan, Han, Zhao, Wei and Qin. Ying Zheng was the king of the kingdom Qin. Through 9 years of wars, he finally conquered all six other kingdoms and became the first emperor of a unified China in 221 BC. That was Qin dynasty ---- the first imperial dynasty of China(not to be confused with the Qing Dynasty, the last dynasty of China). So Ying Zheng named himself "Qin Shi Huang" because "Shi Huang" means "the first emperor" in Chinese.

Qin Shi Huang undertook gigantic projects, including the first version of the Great Wall of China, the now famous city-sized mausoleum guarded by a life-sized Terracotta Army, and a massive national road system. There is a story about the road system:
There were n cities in China and Qin Shi Huang wanted them all be connected by n-1 roads, in order that he could go to every city from the capital city Xianyang.
Although Qin Shi Huang was a tyrant, he wanted the total length of all roads to be minimum,so that the road system may not cost too many people's life. A daoshi (some kind of monk) named Xu Fu told Qin Shi Huang that he could build a road by magic and that magic road would cost no money and no labor. But Xu Fu could only build ONE magic road for Qin Shi Huang. So Qin Shi Huang had to decide where to build the magic road. Qin Shi Huang wanted the total length of all none magic roads to be as small as possible, but Xu Fu wanted the magic road to benefit as many people as possible ---- So Qin Shi Huang decided that the value of A/B (the ratio of A to B) must be the maximum, which A is the total population of the two cites connected by the magic road, and B is the total length of none magic roads.
Would you help Qin Shi Huang?
A city can be considered as a point, and a road can be considered as a line segment connecting two points.
 

 

Input
The first line contains an integer t meaning that there are t test cases(t <= 10).
For each test case:
The first line is an integer n meaning that there are n cities(2 < n <= 1000).
Then n lines follow. Each line contains three integers X, Y and P ( 0 <= X, Y <= 1000, 0 < P < 100000). (X, Y) is the coordinate of a city and P is the population of that city.
It is guaranteed that each city has a distinct location.
 

 

Output
For each test case, print a line indicating the above mentioned maximum ratio A/B. The result should be rounded to 2 digits after decimal point.
 

 

Sample Input
2
4
1 1 20
1 2 30
200 2 80
200 1 100
3
1 1 20
1 2 30
2 2 40
 

 

Sample Output
65.00
70.00
 

 

Source
 

 

Recommend
lcy

 

       题意:

       给出 T 组样例,每个样例都有 N 个点,后给出 N 个点的坐标和值。要求从中选出 n - 1 条路,选中其中一条为魔法路,这时候的 A = 魔法路所连接两个点的总和值, B = n - 1 条路的总和长度值 - 魔法路的长度值。求 A / B 最大。

 

       思路:

       最小生成树 + LCA。因为要求 A / B 最大,相当于求 B 最小,即求最小生成树。求完之后并没有结束,因为此刻还未能确定答案。之后开始枚举任意两个点,使这两个点连边(相当于在枚举魔法边),如果这两个点连接的边并不是生成树上的边,添加之后则必定会生成环,这时候要删除这个环上权值最大的那条边以保证 B 最小(B = min_tree - max_val);如果已经是生成树上的边,则直接删除这条边即可(B = min_tree - G [ i ] [ j ] )。找环则通过 LCA 寻找路径来找,边往上边比较最大值即可。注意数据类型!!!!因为保存边的时候一不小心用了 int 所以导致无限 WA。

 

        AC:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

const int VMAX = 1010;
const int EMAX = 1000010;

typedef struct {
    int root;
    double len;
} fath;

typedef struct {
    double x, y, num;
} node;

typedef struct {
    double len;
    int a, b;
} Map;

int G_ind, n;
double Min_sum;
node no[VMAX];
Map G[EMAX];
double G1[VMAX][VMAX];

int root[VMAX];

int ind;
int fir[VMAX], next[EMAX], v[EMAX];
double w[EMAX];

int cnt;
bool vis[VMAX];
int vs[VMAX * 2], dep[VMAX * 2], id[VMAX];
fath fa[VMAX];
int dp[VMAX * 2][25];

bool cmp (Map a, Map b) { return a.len < b.len; }

void init () {
    G_ind = ind = Min_sum = cnt = 0;
    for (int i = 1; i <= n; ++i) {
        fa[i].root = root[i] = i;
    }
    memset(fir, -1, sizeof(fir));
    memset(G1, 0, sizeof(G1));
    memset(vis, 0, sizeof(vis));
}

void add_edge (int f, int t, double val) {
    v[ind] = t;
    w[ind] = val;
    next[ind] = fir[f];
    fir[f] = ind;
    ++ind;
}

int Find (int x) {
    return root[x] == x ? x : root[x] = Find(root[x]);
}

void Min_tree () {
    sort(G, G + G_ind, cmp);

    int ans = 0;
    for (int i = 0; i < G_ind; ++i) {
        if (ans == n - 1) break;

        int a = Find(G[i].a);
        int b = Find(G[i].b);
        if (a != b) {
            ++ans;
            Min_sum += G[i].len;
            root[a] = b;
            add_edge(G[i].a, G[i].b, G[i].len);
            add_edge(G[i].b, G[i].a, G[i].len);
            G1[G[i].a][G[i].b] = G[i].len;
            G1[G[i].b][G[i].a] = G[i].len;
        } else continue;
    }

}

void dfs (int x, int d) {
    id[x] = cnt;
    dep[cnt] = d;
    vs[cnt++] = x;
    vis[x] = 1;

    for (int e = fir[x]; e != -1; e = next[e]) {
        int V = v[e];
        if (!vis[V]) {
            fa[V].root = x;
            fa[V].len = w[e];
            dfs (V, d + 1);
            vs[cnt] = x;
            dep[cnt++] = d;
        }
    }
}

void RMQ_init () {
    for (int i = 0; i < cnt; ++i) dp[i][0] = i;

    for (int j = 1; (1 << j) <= cnt; ++j) {
        for (int i = 0; i + (1 << j) < cnt; ++i) {
            int a = dp[i][j - 1];
            int b = dp[i + (1 << (j - 1))][j - 1];

            if (dep[a] < dep[b]) dp[i][j] = a;
            else dp[i][j] = b;
        }
    }
}

int RMQ (int L, int R) {
    int len = 0;
    while ((1 << (1 + len)) <= R - L + 1) ++len;

    int a = dp[L][len];
    int b = dp[R - (1 << len) + 1][len];

    if (dep[a] < dep[b]) return a;
    return b;
}

int LCA (int a, int b) {
    int L = min(id[a], id[b]);
    int R = max(id[a], id[b]);

    int node = RMQ(L, R);
    return vs[node];
}

double Find_max_road (int a, int b) {
    int lca = LCA(a, b);

    double Max = 0;
    while (a != lca) {
        Max = max(Max, fa[a].len);
        a = fa[a].root;
    }

    while (b != lca) {
        Max = max(Max, fa[b].len);
        b = fa[b].root;
    }

    return Max;
}

int main() {

    int t;
    scanf("%d", &t);

    while (t--) {
        scanf("%d", &n);

        init();

        for (int i = 1; i <= n; ++i) {
            scanf("%lf%lf%lf", &no[i].x, &no[i].y, &no[i].num);
        }

        for (int i = 1; i <= n - 1; ++i) {
            for (int j = i + 1; j <= n; ++j) {
                double x = (double)no[i].x - (double)no[j].x;
                double y = (double)no[i].y - (double)no[j].y;
                double len = sqrt(x * x + y * y);
                G[G_ind].a = i;
                G[G_ind].b = j;
                G[G_ind++].len = len;
            }
        }

        Min_tree();
        dfs (1, 1);
        RMQ_init();

        double ans = 0;
        for (int i = 1; i <= n - 1; ++i) {
            for (int j = i + 1; j <= n; ++j) {

                double Max;

                if (G1[i][j]) Max = G1[i][j];
                else Max = Find_max_road(i , j);

                double ans1 = Min_sum - Max;
                ans1 = (no[i].num + no[j].num) / ans1;

                ans = max(ans, ans1);
            }
        }

        printf("%.2lf\n", ans);

    }

    return 0;
}

 

 

分享到:
评论

相关推荐

    最小生成树+并查集题目列表.docx

    本资源提供了关于 DFS 枚举组合情况的题目,例如 Qin Shi Huang's National Road System。 最大生成树 最大生成树是一种图论概念,指的是连通图的生成树中具有最大权重的树。本资源提供了关于最大生成树的题目,...

    最小生成树进一步拓展

    次小生成树可以通过证明不存在比最小生成树更小但不相邻的生成树来得出,即如果最小生成树T1不是次小生成树,那么必定存在另一个生成树T',使得T'的边权和小于T1,但这样的T'不属于T1的邻集,与定义矛盾。...

    ACM2020倍增+LCA.pdf

    ACM2020倍增+LCA 本资源主要涉及到两方面的知识点:ST表(Sparse Table)和LCA(Lowest Common Ancestor)。 ST表 ST表是一种预处理数据结构,用于解决Range Query问题,即在一个数组中查询一个范围内的最大或...

    SAS+proc lca浅类别分析安装程序

    在数据分析领域,SAS(Statistical Analysis System)是一款广泛应用的统计软件,提供了各种高级分析功能。其中,PROC LCA(Latent Class Analysis)是SAS中的一个过程,用于执行潜在类别分析,这是一种统计方法,...

    xml关键字查询求SLCA代码

    5. **查询执行**:根据查询语句,系统会生成执行计划,然后利用索引和优化策略来查找SLCA。在实际的系统中,查询执行还包括结果的排序、分页和格式化。 压缩包中的文件"IL"可能是实现代码的一部分,包含了具体算法...

    ACM图论模板合集.pdf

    图论--最短路径生成树(最小边权和)模板 图论--最短路径生成树计数--模板 图论--生成树--次小生成树模板 图论--曼哈顿距离最小生成树模板 图论--生成树计数模板 连通性: 图论--割点--Tarjan模板...

    LCA RMQ 最小公共祖先 区间最小值

    LCA RMQ 最小公共祖先 区间最小值 LCA(Lowest Common Ancestor)和 RMQ(Range Minimum Query)是两种常见的数据结构算法问题。LCA 问题的目的是在一棵树中找到两个结点的最近公共祖先,而 RMQ 问题的目的是在一个...

    图论总结_ftiasch1

    本文将对图论的一些关键概念进行总结,包括最小生成树、最短路径、最近公共祖先(LCA)以及二分图等相关算法。 1. **最小生成树** - **Prim’s Algorithm**: Prim算法是一种贪心算法,用于找到加权无向图的最小...

    Pascal LCA 倍增法详解及代码

    最近公共祖先(LCA)问题在计算机科学,特别是在图论和数据结构中具有重要的应用,尤其是在树形数据结构的处理中。LCA指的是在一棵有根树中,给定两个节点u和v,找到离根最远的那个节点r,使得r既是u的祖先也是v的...

    Tarjan 的 LCA 算法

    最近公共祖先(Lowest Common Ancestor,简称LCA)是图论中的一个重要概念,特别是在树形结构中。在树中,两个节点的最近公共祖先指的是距离根节点最近的那个同时是这两个节点的祖先的节点。在计算机科学中,这个...

    LCA.rar_LCA

    最近公共祖先(Lowest Common Ancestor,简称LCA)是图论中的一个重要概念,主要应用于树形结构的数据问题。在给定的树中,两个节点的最近公共祖先是指距离这两个节点最近的那个共同父节点。在计算机科学中,尤其是...

    LCA-AW2.2.zip

    【LCA词汇复杂度分析软件】是一款用于自然语言处理(NLP)的专业工具,它主要聚焦于语言的复杂度分析。LCA,全称为“Language Complexity Analysis”,此软件旨在帮助用户理解和评估文本的语言难度,这对于教育、...

    RMQ与LCA ACM必备

    例如,在一个树形结构中,A是B和C的LCA,D是E和F的LCA。 1. **Tarjan离线算法**: Tarjan提出了一种离线算法来解决LCA问题,使用并查集维护树结构,并通过深度优先搜索(DFS)进行预处理。每个节点u的father[u]...

    LCA265显示器应用

    LCA265显示器是Systeme Lauer GmbH & Co. KG公司生产的一款专业显示器,用于显示和处理用户数据。在操作这款显示器时,有时需要进行数据传输,特别是文本文件的交换,这通常涉及到与个人计算机(PC)之间的通信。...

    LCA (最近公共祖先) Tarjan & 倍增

    LCA Tarjan: 实现原理 理解:离线算法,建好树后再查询,一次DFS 吧所有查询解决完。 时间复杂度:O(n+q); n个点 q次询问 补一下:链式向前星,并查集 ,Tarjan 代码 #include #include #include #include #...

    LCA51正式版2.06

    LCA51编译器支持标准的C语言,同时优化了针对51系列单片机的代码生成,确保生成的机器码体积小、运行速度快。它还具备强大的调试功能,如断点设置、变量观察、步进执行等,帮助开发者定位和修复程序中的问题。 再者...

    算法课程之相关的 树_堆.pdf

    这篇文档主要涵盖了与树和堆相关的算法知识,其中包括二叉树、完全二叉树、平衡二叉树、图以及最小生成树等相关概念。下面将详细解释这些知识点。 1. **二叉树**:二叉树是一种特殊的图,每个节点最多有两个子节点...

    lca.rar_LCA

    - **Tarjan's offline LCA算法**:利用深度优先搜索遍历整个树,并在线性时间内预处理出所有节点对的LCA信息。 - **Morris遍历**:通过不使用显式的栈空间进行DFS,可以高效地找到LCA,但实现起来相对复杂。 2. *...

Global site tag (gtag.js) - Google Analytics