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;
}
浙公网安备 33010602011771号