HDU 4081-Qin Shi Huang's National Road System

来源:互联网 发布:cmmi软件成熟度模型 编辑:程序博客网 时间:2024/05/20 10:54

Qin Shi Huang's National Road System

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



题目链接:点击打开链接



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.

Sample Input
241 1 201 2 30200 2 80200 1 10031 1 201 2 302 2 40
 

Sample Output
65.0070.00

 

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.


题意:
有一个关于道路系统的故事:中国有n个城市,秦始皇希望它们都能通过n - 1公路连接,这样他就可以从首都咸阳去每个城市。虽然秦始皇是一个暴君,但他希望所有道路的总长度是最低的,这样道路系统就不会花费太多的人的生命。一位名叫徐福 的僧侣告诉秦始皇,他可以用魔法修一条路,这条神奇的路不需要钱也不需要劳动。
但徐福只能为秦始皇修建一条魔法之路。所以秦始皇不得不决定在哪里修建魔法路。秦始皇希望所有没有魔法道路的总长度尽可能小,但徐福希望魔术路尽可能多的人受益——所以秦始皇决定的价值 A/B (A,B)的比例必须是最大的,A 是被魔法路相连的城市的人口的数量,
B是连接 n 个城市路的总长度减去有魔法的道路。
一个城市可以被认为是一个点,而道路可以被认为是连接两点的线段。


分析:
首先我们要求的是 A/B 的最大值,我们知道A 代表被魔法之路相连的两个城市的人口总数,B是 n-2 条路之和(因为不包括那条魔法之路),我们首先要将最小最小生成树求出来,在求最小生成树的同时,我们应该将最小生成树中的任意两点之间的最大距离保留一下,因为我们也不知道那条魔法之路是否就是最小生成树里的边,如果在就直接用所求的最小生成树减去那条边,如果不在,就要去掉被魔法之路相连的两个点在最小生成树里的最大边。



#include<iostream>#include<algorithm>#include<string.h>#include<stdio.h>#include<math.h>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 1002;double Map[maxn][maxn];///存两点之间的距离bool mark[maxn][maxn];///标记最小生成树里的边double maxcost[maxn][maxn];///maxcost[i][j]用来存放最小生成树中节点i到节点j中的那条最大边的权值int closest[maxn];///在最小生成树中与该点相连的上一个点double low[maxn];int vis[maxn];///标记数组int N;struct pos{    int x;     ///坐标    int y;    int p;     ///人口数量}point[maxn];double dis(struct pos p1,struct pos p2)///计算两地之间的距离{    double temp = ((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))*1.0;    return sqrt(temp);}double prim(){    double ans = 0,min1;    int bj;    memset(mark,false,sizeof(mark));    memset(maxcost,0,sizeof(maxcost));    for(int i = 1; i <= N; i++)    {        low[i] = Map[1][i];///以1作为源点        closest[i] = 1;    }    memset(vis,0,sizeof(vis));    vis[1] = 1;///将1标记    for(int i = 1; i < N; i++)    {        min1 = INF;        for(int j = 1; j <= N; j++)        {            if(!vis[j] && low[j]<min1)            {                min1 = low[j];                bj = j;            }        }        vis[bj] = 1;        ans += min1;        int pre = closest[bj];        mark[pre][bj] = mark[bj][pre] = true; ///代表该边被最小生成树选中        maxcost[pre][bj] = min1; ///pre到u只有自身一条边,所以maxcost为Min        for(int j = 1; j <= N; j++)        {            if(vis[j]==1 && j != bj)  ///vis[j]=1是为了只更新最小生成树中的值                maxcost[j][bj] = maxcost[bj][j] = max(maxcost[j][pre],maxcost[pre][bj]);        }        for(int j = 1; j <= N; j++)///更新可以被更新的边        {            if(!vis[j] && Map[bj][j]<low[j])            {                low[j] = Map[bj][j];                closest[j] = bj;///更新的同时将节点也更新            }        }    }    return ans;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&N);///测试数据的组数        for(int i = 1; i <= N; i++)///输入城市的坐标和该城市的人口            scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].p);        for(int i = 1; i <= N; i++)        {            for(int j = i+1; j <= N; j++)                Map[i][j] = Map[j][i] = dis(point[i],point[j]);///双向存两地之间的距离        }        double MST;        MST = prim();///跑一边最小生成树        double sum = -1;        for(int i = 1; i <= N; i++)        {            Map[i][i] = 0; ///自身到自身的距离是0            for(int j = 1; j <= N; j++)            {                if(i != j)                {                    if(mark[i][j])  ///用魔法修的边i,j是最小生成树中的边                        sum = max(sum,(point[i].p+point[j].p)/(MST-Map[i][j]));                    else                        sum = max(sum,(point[i].p+point[j].p)/(MST-maxcost[i][j]));                }            }        }        printf("%.2lf\n",sum);    }    return 0;}






 
阅读全文
0 0
原创粉丝点击