ybt1712 汉堡店

1712:汉堡店

时间限制: 1000 ms 内存限制: 262144 KB

【题目描述】

市中心有\(N\)家汉堡店,每两家汉堡店间都有一条双向道路。由于汉堡店间的路太过于复杂,决定只保留其中\(N−1\)条道路(必须保证每两家汉堡店间都连通),其它道路都无视掉。

经过一段时间的考虑,准备吃光两家汉堡店(两家汉堡店在新图中必须有边)。

假设吃光了\(a,b\)两家的汉堡,那么就会得到\(A/B\)的愉悦度:其中:\(A=P_a+P_b(P_i是第\)i\(家汉堡店的美味度);\)B=\(除了道路\)(a,b)$外,新图中所有道路的权值之和(道路的权值为两家汉堡店之间的欧几里德距离)。

想知道他最多得到的愉悦度是多少。

【输入】

第一行一个整数\(N\),表示汉堡店的个数。

接下来\(n\)行,每行包括三个整数\(x,y,P\),描述一个汉堡店的信息,其中\((x,y)\)为该汉堡店的直角坐标,\(P\)为该汉堡店的美味度。

【输出】

最大的愉悦度(保留两位小数)。

【输入样例】

4
1 1 20
1 2 30
200 2 80
200 1 100

【输出样例】

65.00

【样例说明】

保留\((1,2),(3,4),(2,4)\)这3条边,并且选择\((2,4)\)这条边,则\(A=30+100=130,B=1+1=2,A/B=65\),可以证明不存在更大的解。

【数据规模及约定】

对于20%数据,满足\(2<N≤5\)

对于50%数据,满足\(2<N≤50\)

对于100%数据,满足\(2<N≤1000,0≤X,Y≤1000,0<P<10000\)


最小生成树+树上倍增求最大值


#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
struct node
{
	int x,y;
}pt[maxn];
int n;
int p[maxn],pre[maxn];
double ds[maxn][maxn];
double dis[maxn],diss;
bool bz[maxn];
auto max(auto a,auto b)
{
	return a>b?a:b;
}
double jsds(int i,int j)
{
	return sqrt((pt[i].x-pt[j].x)*(pt[i].x-pt[j].x)+(pt[i].y-pt[j].y)*(pt[i].y-pt[j].y));
}
struct edge
{
	int u,v,nxt;
	double w;
}e[2020];
int head[maxn],js;
void addage(int u,int v,double w)
{
	e[++js].u=u;e[js].v=v;e[js].w=w;
	e[js].nxt=head[u];head[u]=js;
}
int dep[maxn],f[maxn][15];
double ff[maxn][15];
void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==fa)continue;
		ff[v][0]=e[i].w;f[v][0]=u;
		for(int i=1;f[f[v][i-1]][i-1];i++)
			f[v][i]=f[f[v][i-1]][i-1],ff[v][i]=max(ff[v][i-1],ff[f[v][i-1]][i-1]);
		dfs(v,u);
	}
}
double ans=0;
double work(int u,int v)
{
	int uu=u,vv=v;
	double tmp=0;
	if(dep[u]<dep[v])swap(u,v);
	for(int i=10;i>=0;--i)
	{
		if(dep[f[u][i]]>=dep[v])
		{
			tmp=max(tmp,ff[u][i]);
			u=f[u][i];
		}
	}
	if(u==v)return 1.0*(p[uu]+p[vv])/(diss-tmp);
	for(int i=10;i>=0;--i)
	{
		if(f[u][i]!=f[v][i])
		{
			tmp=max(tmp,ff[u][i]);
			tmp=max(tmp,ff[v][i]);
			u=f[u][i];
			v=f[v][i];
		}
	}
	tmp=max(tmp,ff[u][0]);
	tmp=max(tmp,ff[v][0]);
	return 1.0*(p[uu]+p[vv])/(diss-tmp);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d%d%d",&pt[i].x,&pt[i].y,&p[i]);
	for(int i=1;i<=n;++i)
		for(int j=i+1;j<=n;++j)
			ds[i][j]=ds[j][i]=jsds(i,j);
	for(int i=1;i<=n;++i)dis[i]=30000;
	dis[1]=0;pre[1]=0;
	for(int i=1;i<=n;++i)
	{
		double mn=30000;
		int no;
		for(int j=1;j<=n;++j)
			if(!bz[j]&&dis[j]<mn)no=j,mn=dis[j];
		diss+=mn;bz[no]=1;
		if(pre[no])
		{
			addage(no,pre[no],mn);
			addage(pre[no],no,mn);
		}
		for(int j=1;j<=n;++j)
			if(!bz[j]&& dis[j]>ds[no][j])dis[j]=ds[no][j],pre[j]=no;
	}
	dfs(1,0);
	for(int i=1;i<=n;++i)
		for(int j=i+1;j<=n;++j)
		{
			if(pre[i]==j||pre[j]==i)
			{
				double tp=(double)(p[i]+p[j])/(diss-ds[i][j]);
				ans=ans>tp?ans:tp;
			}
			else
			{
				double tp=work(i,j);
				ans=max(ans,tp);
			}
		}
	printf("%.2lf",ans);
	return 0;
}

posted on 2025-03-13 09:37  gryzy  阅读(66)  评论(0)    收藏  举报

导航