比赛 |
cdcqの省选膜你赛 |
评测结果 |
AAAAAWAAAAAWAAWWAAAA |
题目名称 |
秘术「天文密葬法」 |
最终得分 |
80 |
用户昵称 |
scpointer |
运行时间 |
2.056 s |
代码语言 |
C++ |
内存使用 |
7.94 MiB |
提交时间 |
2017-04-11 21:56:54 |
显示代码纯文本
#include <cstdio>
#include <vector>
using namespace std;
inline int RD()
{
int res;char cr;
while( (cr=getchar())<'0' || cr>'9'); res=cr-'0';
while( (cr=getchar())>='0' && cr<='9') res=res*10+cr-'0';
return res;
}
#define N 200050
#define eps 1e-4
#define pb push_back
#define VI vector<int>
#define Min(a,b) ((a)<(b)?(a):(b))
int ai[N],bi[N];
int qlen;
double ans,nowC;
vector<int> eg[N];
int vis[N],sz[N];
int sz_dfs(int p,int fa)
{
sz[p]=1;
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt] && pt!=fa)
sz[p]+=sz_dfs(pt,p);
}
return sz[p];
}
int halfsize;
int findroot(int p,int fa)
{
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt] && pt!=fa && sz[pt]>=halfsize)
return findroot(pt,p);
}
return p;
}
int tim[N],timetip;
double mn[N];
bool solve(int p,int fa,int flo,double tot)
{
if(flo-qlen>0) return 0;
tot+=ai[p]-bi[p]*nowC;
if(tim[qlen-flo]==timetip && mn[qlen-flo]+tot<0)
return 1;
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt] && pt!=fa)
{
if(solve(pt,p,flo+1,tot))
return 1;
}
}
return 0;
}
void add(int p,int fa,int flo,double tot)
{
if(flo-qlen>0) return;
tot+=ai[p]-bi[p]*nowC;
if(tim[flo]<timetip)
tim[flo]=timetip,mn[flo]=tot;
else
mn[flo]=Min(mn[flo],tot);
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt] && pt!=fa)
add(pt,p,flo+1,tot);
}
}
bool check(int p)
{
tim[0]=++timetip;
mn[0]=ai[p]-bi[p]*nowC;
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt])
{
if(solve(pt,p,1,0))
return 1;
add(pt,p,1,mn[0]);
}
}
return 0;
}
void divis(int p)
{
sz_dfs(p,0);
halfsize=sz[p]>>1;
p=findroot(p,0);
double l=0,r=ans,mid;
while((r-l)>eps)
{
nowC=mid=(l+r)/2;
if(check(p)) r=mid;
else l=mid;
}
ans=Min(ans,r);
vis[p]=1;
vector<int> &V=eg[p];
for(int i=0,lim=V.size();i<lim;i++)
{
int pt=V[i];
if(!vis[pt])
divis(pt);
}
}
int main()
{
freopen("cdcq_b.in","r",stdin);
freopen("cdcq_b.out","w",stdout);
int n=RD();qlen=RD()-1;
for(int i=1;i<=n;i++)
ai[i]=RD();
for(int i=1;i<=n;i++)
bi[i]=RD();
if(qlen==-2 || qlen==0)
{
ans=ai[1]/((double)bi[1]);
for(int i=1;i<=n;i++)
ans=Min(ans,ai[i]/((double)bi[i]));
printf("%.2lf\n",ans);
return 0;
}
ans=1e13;
for(int i=1;i<=n-1;i++)
{
int p1,p2;p1=RD();p2=RD();
eg[p1].pb(p2);eg[p2].pb(p1);
}
divis(1);
printf("%.2lf\n",ans);
}