现在的位置: 首页 > 综合 > 正文

BUPT 238 2011ACM北京赛区现场赛A题

2017年11月22日 ⁄ 综合 ⁄ 共 3883字 ⁄ 字号 评论关闭

 

A. Qin Shi Huang's National Road System

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).

2

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

241

1 20

1 2 30

200 2 80

200 1 100

31

1 20

1 2 30

2 2 40

Sample Output

65.00

70.00

 

先求一次最小生成树

然后暴力枚举两点,两点之间的边假设为魔法路

然后DFS去找环上面的最长边,并且用枚举得到的边来替换他

然后计算一个A/B,维护一个最大值即可

 

比赛的时候确实没想到啊。。

 

我的代码:

#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#define inf 99999999

using namespace std;

struct node
{
	int v1;
	int v2;
	double len;
};

struct point
{
	double x;
	double y;
	double p;
};

bool map[1005][1005];
point pt[1005];
node e[1005];
vector<int>tree[1005];
double dis[1005][1005];
double dp[1005][1005];
double ans,MAX;
int out[1005];
int n;

double dist(point a,point b)
{
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void init()
{
	int i,j;
	MAX=0;
	for(i=1;i<=n;i++)
	{
		tree[i].clear();
		for(j=1;j<=n;j++)
			dis[i][j]=dist(pt[i],pt[j]);
	}
}

double max(double a,double b)
{
	if(a>b)
		return a;
	else
		return b;
}

double prim()
{
	int i,j,vx,vy,min;
	double minl,ret=0,leng;
	for(i=1;i<=n-1;i++)
	{
		e[i].v1=1;
		e[i].v2=i+1;
		e[i].len=dis[1][i+1];
	}
	for(i=1;i<=n-1;i++)
	{
		min=-1;
		minl=inf;
		for(j=i;j<=n-1;j++)
		{
			if(e[j].len<minl)
			{
				minl=e[j].len;
				min=j;
			}
		}
		if(min==-1)
			break;
		tree[e[min].v1].push_back(e[min].v2);
		tree[e[min].v2].push_back(e[min].v1);
		ret=ret+minl;
		MAX=max(MAX,minl);
		swap(e[i],e[min]);
		vx=e[i].v2;
		for(j=i+1;j<=n-1;j++)
		{
			vy=e[j].v2;
			leng=dis[vx][vy];
			if(leng<e[j].len)
			{
				e[j].len=leng;
				e[j].v1=vx;
			}
		}
	}
	return ret;
}

void dfs(int x,int pre)
{
	out[x]=pre;
	int i,v;
	for(i=0;i<tree[x].size();i++)
	{
		v=tree[x][i];
		if(v!=pre)
			dfs(v,x);
	}
}

int main()
{
	int i,t,j;
	double x,y,p,A,B;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		ans=0;
		for(i=1;i<=n;i++)
		{
			scanf("%lf%lf%lf",&x,&y,&p);
			pt[i].x=x;
			pt[i].y=y;
			pt[i].p=p;
		}
		init();
		double temp=prim();
		for(i=1;i<=n;i++)
			for(j=0;j<tree[i].size();j++)
			{
				int v=tree[i][j];
				A=pt[i].p+pt[v].p;
				B=temp-dis[i][v];
				ans=max(ans,A/B);
			}
		for(i=1;i<=n;i++)
		{
			for(j=i+1;j<=n;j++)
			{
				if((pt[i].p+pt[j].p)/(temp-MAX)>ans)
				{
					dfs(i,0);
					int k=j;
					B=0,A=pt[i].p+pt[j].p;
					while(out[k]&&k!=i)
					{
						B=max(dis[k][out[k]],B);
						k=out[k];
					}
					ans=max(ans,A/(temp-B));
				}
			}
		}
		printf("%.2lf\n",ans);
	}
	return 0;
}

 

抱歉!评论已关闭.