http://codeforces.com/gym/100851
第一眼,这不是noip2015DAY2T1原题吗。。。。
然后发现不太行,不过变化一下就行了
先二分一个最大跳的距离mid,去判断能不能在一个额外的石子的条件下,使得每一跳都小于mid,由于从河岸到每个石子是垂直跳的,我们还要在河岸处每边增加n个点,来表示从河岸直接跳到对应点的距离,设置一个左边的超级源点,右边的超级汇点,分别开始dfs,标记哪些点左边能再不超过mid的情况下直接跳到,右边也是一样。然后枚举u,v两个点,如果左边能到u点,右边能到v点,且dist(u,v)<=2*mid,那么mid就是可行的,把石子加在u,v中间就行了。
#include<bits/stdc++.h>
#define maxl 3010
using namespace std;
const double eps=1e-5;
int w,n,S,T,cnt;
int ehead[maxl];
struct node
{
int x,y;
}a[maxl];
struct ed
{
int to,nxt;
double l;
}e[2000*2000*2];
double ansx,ansy;
bool visS[maxl],visT[maxl];
inline double dist(double x,double y)
{
return sqrt(x*x+y*y);
}
inline void add(int u,int v,double l)
{
e[++cnt].to=v;e[cnt].l=l;
e[cnt].nxt=ehead[u];ehead[u]=cnt;
}
inline void prework()
{
scanf("%d%d",&w,&n);
for(int i=1;i<=3*n+2;i++)
ehead[i]=0;
S=3*n+1;T=3*n+2;
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
for(int i=1;i<=n;i++)
{
a[n+i].x=0,a[n+i].y=a[i].y;
add(S,n+i,0);
add(n+i,i,a[i].x);
a[2*n+i].x=w;a[2*n+i].y=a[i].y;
add(T,2*n+i,0);
add(2*n+i,i,w-a[i].x);
}
double l;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
l=dist(a[i].x-a[j].x,a[i].y-a[j].y);
add(i,j,l);add(j,i,l);
}
}
inline void dfs1(int u,double mid)
{
int v;visS[u]=true;
for(int i=ehead[u];i;i=e[i].nxt)
if(e[i].l<mid+eps)
{
v=e[i].to;
if(!visS[v])
dfs1(v,mid);
}
}
inline void dfs2(int u,double mid)
{
int v;visT[u]=true;
for(int i=ehead[u];i;i=e[i].nxt)
if(e[i].l<mid+eps)
{
v=e[i].to;
if(!visT[v])
dfs2(v,mid);
}
}
inline bool jug(double mid)
{
for(int i=1;i<=3*n+2;i++)
visS[i]=false,visT[i]=false;
dfs1(S,mid);
dfs2(T,mid);
for(int i=1;i<=3*n;i++)
for(int j=1;j<=3*n;j++)
if(visS[i] && visT[j])
{
if(dist(a[i].x-a[j].x,a[i].y-a[j].y)<=2*mid+eps)
{
ansx=(1.0*a[i].x+a[j].x)/2;
ansy=(1.0*a[i].y+a[j].y)/2;
return true;
}
}
return false;
}
inline void mainwork()
{
if(n==0)
{
ansx=1.0*w/2;ansy=0;
return;
}
double l=0,r=w,mid;
while(l+eps<r)
{
mid=(l+r)/2;
if(jug(mid))
r=mid;
else
l=mid;
}
}
inline void print()
{
printf("%.3f %.3f",ansx,ansy);
}
int main()
{
freopen("froggy.in","r",stdin);
freopen("froggy.out","w",stdout);
prework();
mainwork();
print();
return 0;
}