[SDOI2012]拯救小云公主

题解:

是一个不错的题目

 首先我们可以考虑二分答案

然后变成判定性问题

对于每个画一个圆 当其会被阻断时就是答案

阻断有四种情况 左下 上下 左右 右上

但是这样是n^2a(n)*logn的

考虑直接spfa 那是kn^2的

但是洛谷的空间是128的。。有点小

代码:

// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
#define N 10000000
#define INF 1e9
double x[5000],y[5000],dis[5000];
int head[5000];
int n,a,b,l;
bool inq[5000];
struct re{
    int a,b;
    double c;
}e[N];
void arr(int x,int y,double z)
{
    e[++l].a=head[x];
    e[l].b=y;
    e[l].c=z;
    head[x]=l;
}
queue<int>q;
int cnt=0,cnt2;
void spfa()
{
    while (!q.empty())
    {
        cnt++;
        int xx=q.front(); q.pop();
        int u=head[xx];
        while (u)
        {
            cnt2++;
            int v=e[u].b;
            if (max(dis[xx],e[u].c)<dis[v])
            {
                dis[v]=max(dis[xx],e[u].c);
                if (!inq[v])
                {
                    inq[v]=1; q.push(v);
                }
            }
            u=e[u].a;
        }
        inq[xx]=0;
    }
}
int main()
{
    //std::ios::sync_with_stdio(false);
    cin>>n>>a>>b;
    for (int i=1;i<=n;i++) cin>>x[i]>>y[i];
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
      {
          double s=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
          s/=2;
        arr(i,j,s);
      }
    int s1=n+1,s2=n+2,s3=n+3,s4=n+4;
    for (int i=1;i<=n;i++)
    {
        arr(s1,i,x[i]-1); arr(i,s1,x[i]-1);
        arr(s2,i,b-y[i]); arr(i,s2,b-y[i]);
        arr(s3,i,y[i]-1); arr(i,s3,y[i]-1);
        arr(s4,i,a-x[i]); arr(i,s4,a-x[i]);
    }
    double ans=INF;
    for (int i=1;i<=s4;i++) dis[i]=INF;
    dis[s1]=0; dis[s2]=0;q.push(s1); q.push(s2);
    spfa();
    ans=min(ans,dis[s3]); ans=min(ans,dis[s4]);
    ans=min(ans,dis[s4]); ans=min(ans,dis[s3]);
    printf("%.2f",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/8818785.html