NOIP 模拟 $80\; \rm 滑稽树下你和我$
题解 \(by\;zj\varphi\)
口胡一下:
采取最优策率,使得存在一种移动到叶子节点的路径最大距离最小。
二分答案,每次 \(bfs\) 看能否找到一条路径,每次找最短的,使得两个人都能到叶子节点。
有一些很神奇的技巧,看代码。
Code
#include<bits/stdc++.h>
#define ri signed
#define pd(i) ++i
#define bq(i) --i
#define func(x) std::function<x>
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
#define debug1(x) std::cerr << #x"=" << x << ' '
#define debug2(x) std::cerr << #x"=" << x << std::endl
#define Debug(x) assert(x)
struct nanfeng_stream{
template<typename T>inline nanfeng_stream &operator>>(T &x) {
bool f=false;x=0;char ch=gc();
while(!isdigit(ch)) f|=ch=='-',ch=gc();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();
return x=f?-x:x,*this;
}
}cin;
}
using IO::cin;
namespace nanfeng{
#define fi first
#define se second
#define mk std::make_pair
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
using db=double;
using ll=long long;
static const int N=1e3+7;
static const db eps=1e-8;
int first[N],deg[N],vis[N][N],U[N],V[N],t=2,n,stx,sty,tim;
struct edge{int v,nxt;}e[N<<1];
auto add=[](int u,int v) {
e[t]={v,first[u]},first[u]=t++;
e[t]={u,first[v]},first[v]=t++;
++deg[u],++deg[v];
};
ll X[N],Y[N];
auto Get=[](int x,int y) {return sqrt(1.0*(X[x]-X[y])*(X[x]-X[y])+1.0*(Y[x]-Y[y])*(Y[x]-Y[y]));};
auto Getdis(int x,int y,int z) {
if ((X[x]-X[y])*(X[z]-X[y])+(Y[x]-Y[y])*(Y[z]-Y[y])>0&&(X[x]-X[z])*(X[y]-X[z])+(Y[x]-Y[z])*(Y[y]-Y[z])>0)
return std::abs((X[y]-X[x])*(Y[z]-Y[x])-(Y[y]-Y[x])*(X[z]-X[x]))/Get(y,z);
return cmin(Get(x,y),Get(x,z));
};
inline int main() {
FI=freopen("tree.in","r",stdin);
FO=freopen("tree.out","w",stdout);
cin >> n >> stx >> sty;
for (ri i(1);i<=n;pd(i)) cin >> X[i] >> Y[i];
for (ri i(1);i<n;pd(i)) cin >> U[i] >> V[i],add(U[i],V[i]);
db l=Get(stx,sty),r=1.5e6,res;
auto check=[&](db lim) {
++tim;
std::queue<std::pair<int,int>> que;
auto add=[&](int x,int y) {if (vis[x][y]^tim&&Getdis(x,U[y],V[y])<=lim) vis[x][y]=tim,que.push(mk(x,y));};
for (ri i(first[stx]);i;i=e[i].nxt) add(sty,i>>1);
for (ri i(first[sty]);i;i=e[i].nxt) add(stx,i>>1);
while(!que.empty()) {
int x=que.front().fi,y=que.front().se;
que.pop();
if (deg[x]==1&°[U[y]]==1&&Get(x,U[y])<=lim) return true;
if (deg[x]==1&°[V[y]]==1&&Get(x,V[y])<=lim) return true;
for (ri i(first[x]);i;i=e[i].nxt)
add(e[i].v,y),add(U[y],i>>1),add(V[y],i>>1);
}
return false;
};
while(r-l>eps) {
db mid=(l+r)/2;
if (check(mid)) res=mid,r=mid;
else l=mid;
}
printf("%.8lf\n",res);
return 0;
}
}
int main() {return nanfeng::main();}