Qin Shi Huang's National Road System
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1287 Accepted Submission(s): 475
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.

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.
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
题目大意:秦始皇要在n个城市间建n-1条路,使得它们连通,对于每个城市,给出其坐标(x,y)和该城市的人口数(p)。现定义每条路的花费就是这条路的长度,给你一次使用魔法的机会(使所建n-1条路的其中一条花费为0),问如何建,使得使用魔法的那条路关联的两个城市人口数之和(A)除以建路的总花费(B),即A/B最大,输出这个最大值。
分析:先生成一棵最小生成树,枚举树上的每一条边,这条边把n个城市分为两部分,分别找出它们中人口数最大的城市(意思是:在这两个城市建那条使用魔法的路,代替枚举的那条边),照这样求出A/B,取最大的!这题要保存最小生成树的边
krusal 703ms
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1002;
const int M=500050;
bool vis[N];
vector<int> map[N];
struct edge
{
int x,y;double d;
bool operator<(edge a)const{return d<a.d;}
}e[M],res[N];
int n,cnt,set[N];
double sum;
struct point{int x,y,po;}p[N];
double dis(point a,point b){return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));}
int find(int x)
{
if(set[x]!=x) set[x]=find(set[x]);
return set[x];
}
bool Union(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx==fy) return false;
set[fy]=fx;
return true;
}
void krusal()
{
int i,j=0;
sort(e,e+cnt);
for(i=1;i<=n;i++)set[i]=i;
for(i=0;i<cnt;i++)
{
if(Union(e[i].x,e[i].y))
{
map[e[i].x].push_back(e[i].y);
map[e[i].y].push_back(e[i].x);
sum+=e[i].d;
res[j]=e[i];
j++;
}
if(j==n-1)return;
}
}
int maxpo;
void dfs(int x)
{
int i;vis[x]=1;
if(p[x].po>maxpo)maxpo=p[x].po;
for(i=0;i<map[x].size();i++)if(!vis[map[x][i]])dfs(map[x][i]);
}
void pre()
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].po);map[i].clear();}
cnt=0;
for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)
{
e[cnt].x=i;e[cnt].y=j;
e[cnt].d=dis(p[i],p[j]);
cnt++;
}
sum=0;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
pre();
krusal();
double ans=0,tmp;
for(i=0;i<n-1;i++)
{
int x=res[i].x,y=res[i].y;
tmp=0;
memset(vis,0,sizeof(vis));
vis[y]=true;maxpo=0;dfs(x);
tmp+=maxpo;
memset(vis,0,sizeof(vis));
vis[x]=true;maxpo=0;dfs(y);
tmp+=maxpo;
tmp/=(sum-res[i].d);
if(tmp>ans)ans=tmp;
}
printf("%.2lf\n",ans);
}
return 0;
}
prim 93ms
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
using namespace std;
const int N=1002;
bool vis[N];
vector<int> map[N];
struct edge
{
int x,y;double d;
}res[N];
int n;
double sum,a[N][N];
struct point{int x,y,po;}p[N];
double dis(point a,point b){return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));}
void prim()
{
double lowcost[N];
int i,j,k,closet[N];
for(i=2;i<=n;i++)
{
lowcost[i]=a[1][i];
closet[i]=1;
}
for(i=0;i<n-1;i++)
{
double min=1e20;
for(j=2;j<=n;j++)
{
if(lowcost[j]>0&&lowcost[j]<min)
{
min=lowcost[j];
k=j;
}
}
res[i].x=closet[k];res[i].y=k;res[i].d=min;
map[k].push_back(res[i].x);
map[res[i].x].push_back(k);
sum+=min;lowcost[k]=-1;
for(j=2;j<=n;j++)
{
if(a[k][j]<lowcost[j])
{
lowcost[j]=a[k][j];
closet[j]=k;
}
}
}
}
int maxpo;
void dfs(int x)
{
int i;vis[x]=1;
if(p[x].po>maxpo)maxpo=p[x].po;
for(i=0;i<map[x].size();i++)if(!vis[map[x][i]])dfs(map[x][i]);
}
void pre()
{
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].po);map[i].clear();}
for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)a[i][j]=a[j][i]=dis(p[i],p[j]);
sum=0;
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
pre();
prim();
double ans=0,tmp;
for(i=0;i<n-1;i++)
{
int x=res[i].x,y=res[i].y;
tmp=0;
memset(vis,0,sizeof(vis));
vis[y]=true;maxpo=0;dfs(x);
tmp+=maxpo;
memset(vis,0,sizeof(vis));
vis[x]=true;maxpo=0;dfs(y);
tmp+=maxpo;
tmp/=(sum-res[i].d);
if(tmp>ans)ans=tmp;
}
printf("%.2lf\n",ans);
}
return 0;
}