zoukankan      html  css  js  c++  java
  • NOIP 模拟 $16; m Star Way To Heaven$

    题解 (by;zjvarphi)

    看懂题!!!

    从最左穿到最右,一定会经过两个星星之间或星星和边界之间,那么我们穿过时当前最优一定是走中点

    而我们要求最小的距离最大,那么我们将所有星星和边界(上下边界分别设为一个点)连成一个完全图,在图上跑出来一棵最小生成树

    那么在最小生成树上的每条边的中点到边的端点一定比这个点到其它所有点的距离小,所以我们只需要找到一条在最小生成树上最大的边

    注意,这道题是一个完全图,跑 ( m kruskal) 当常数大时就 ( m TLE) 了,所以跑 (prim)

    (prim) 算法从一个边界开始找,当找到另一个边界时就可以停止了,因为这是我一定会穿过从一个边界到另一个边界的连线,而此时已经找到了

    Code
    #include<bits/stdc++.h>
    #define ri register signed
    #define p(i) ++i
    using namespace std;
    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)?EOF:*p1++
        template<typename T>inline void read(T &x) {
            ri f=1;x=0;register char ch=gc();
            while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
            while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
            x=f?x:-x;
        }
    }
    using IO::read;
    namespace nanfeng{
        #define cmax(x,y) ((x)>(y)?(x):(y))
        #define cmin(x,y) ((x)>(y)?(y):(x))
        #define FI FILE *IN
        #define FO FILE *OUT
        typedef double db;
        static const int N=6e3+7;
        int vis[N],n,m,k;
        double dis[N],mx;
        struct node{
            int x,y;
            db Getdis(node tmp) {return sqrt((db)(this->x-tmp.x)*(db)(this->x-tmp.x)+(db)(this->y-tmp.y)*(db)(this->y-tmp.y));}
        }pnt[N];
        inline int main() {
            // FI=freopen("nanfeng.in","r",stdin);
            // FO=freopen("nanfeng.out","w",stdout);
            read(n),read(m),read(k);
            for (ri i(1);i<=k;p(i)) {
                read(pnt[i].x),read(pnt[i].y);
                dis[i]=m-pnt[i].y;
            }
            dis[k+1]=m;
            while(1) {
                int cur=0;
                for (ri i(1);i<=k+1;p(i)) 
                    if (!vis[i]&&(!cur||dis[i]<dis[cur])) cur=i;
                vis[cur]=1;
                mx=cmax(mx,dis[cur]);
                if (cur==k+1) break; 
                for (ri v(1);v<=k;p(v)) 
                    if (!vis[v]) dis[v]=min(dis[v],pnt[cur].Getdis(pnt[v]));
                dis[k+1]=min(dis[k+1],1.0*pnt[cur].y);
            }
            printf("%.10lf
    ",mx/2.0);
            return 0;
        }  
    }
    int main() {return nanfeng::main();} 
    
  • 相关阅读:
    android模拟器加速
    QtEmbedded鼠标驱动流程分析(上)
    QML Tutorial 1 Basic Types
    android 版本
    【转】右键菜单大揭密
    【转】设置右键显示/隐藏系统文件
    【转】自己做的登录界面五款正常尺寸+一款宽屏【手把手教You如何制作登录界面】
    【转】如何添加鼠标右键菜单里的快捷图标
    【转】鼠标右键菜单设置大全
    【技术贴】我的文档不见了,我的文档消失了,我的电脑没有我的文档的解决办法。
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15019101.html
Copyright © 2011-2022 走看看