zoukankan      html  css  js  c++  java
  • luogu P3297 [SDOI2013]逃考

    传送门

    gugugu

    首先每个人管理的区域是一个多边形,并且整个矩形是被这样的多边形填满的.现在的问题是求一条经过多边形最少的路径到达边界,这个可以最短路.

    现在的问题是建图,显然我们应该给相邻的多边形连边,考虑一个人和另一个人的多边形交界线,这个线就是两点线段的中垂线,于是我们可以每次把一个人所有的分界线和矩形边界拿出来求一个半平面交,如果某条边在半平面交上就和对应点连边就好了,矩形边界在半平面交上就和外面连边.最后求起点所在多边形到外面的最短路

    然后我半平面交写错,就写了半天qwq

    #include<bits/stdc++.h>
    #define LL long long
    #define db long double
    #define il inline
    
    using namespace std;
    const int N=600+10;
    const db eps=1e-10;
    il LL rd()
    {
        LL x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[N*N],nt[N*N],hd[N],tot;
    void add(int x,int y){++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;}
    struct point
    {
        db x,y;
        point(){}
        point(db nx,db ny){x=nx,y=ny;}
        point operator - (const point &bb) const {return point(x-bb.x,y-bb.y);}
        db operator * (const point &bb) const {return x*bb.x+y*bb.y;}
        db operator ^ (const point &bb) const {return x*bb.y-y*bb.x;}
    }a[N],sht;
    db sq(db x){return x*x;}
    db dis(point aa,point bb){return sqrt(sq(bb.x-aa.x)+sq(bb.y-aa.y));}
    db ang(point aa,point bb){return atan2((bb.y-aa.y),(bb.x-aa.x));}
    struct line
    {
        int ii;
        point x,y;
        db k,b,ag;
        line(){}
        line(int id,point nx,point ny)
        {
            ii=id;
            x=nx,y=ny;
            k=fabs(x.x-y.x)>eps?(x.y-y.y)/(x.x-y.x):1e18;
            b=k<1e17?x.y-k*x.x:x.x;
            ag=ang(x,y);
        }
        bool operator < (const line &bb) const {return fabs(ag-bb.ag)>eps?ag<bb.ag:dis(sht,x)<dis(sht,bb.x);}
    }lb[N],q[N];
    point jiao(line aa,line bb)
    {
        db x=max(aa.k,bb.k)<1e17?(bb.b-aa.b)/(aa.k-bb.k):(aa.k>bb.k?aa.b:bb.b);
        db y=aa.k<bb.k?aa.k*x+aa.b:bb.k*x+bb.b;
        return point(x,y);
    }
    int n,tp;
    int ll,rr,di[N];
    bool v[N];
    db mx,my,sx,sy;
    
    int main()
    {
        int T=rd();
        while(T--)
        {
            memset(hd,0,sizeof(hd)),tot=0;
            n=rd();
            mx=rd(),my=rd(),sx=rd(),sy=rd();
            for(int i=1;i<=n;++i)
            {
                int x=rd(),y=rd();
                a[i]=point(x,y);
            }
            lb[0].ag=-2333;
            for(int i=1;i<=n;++i)
            {
                sht=a[i];
                int m=0;
                for(int j=1;j<=n;++j)
                    if(i!=j)
                    {
                        point md=point((a[i].x+a[j].x)/2,(a[i].y+a[j].y)/2);
                        db kk=fabs(a[i].x-a[j].x)>eps?-1/((a[i].y-a[j].y)/(a[i].x-a[j].x)):0,bb=md.y-kk*md.x;
                        point xx=point(md.x-1,kk*(md.x-1)+bb),yy=point(md.x+1,kk*(md.x+1)+bb);
                        if(fabs(a[i].y-a[j].y)<eps) xx=point(md.x,md.y-1),yy=point(md.x,md.y+1);
                        if(((xx-a[i])^(yy-a[i]))<eps) swap(xx,yy);
                        lb[++m]=line(j,xx,yy);
                    }
                lb[++m]=line(0,point(0,my),point(0,0));
                lb[++m]=line(0,point(mx,my),point(0,my));
                lb[++m]=line(0,point(mx,0),point(mx,my));
                lb[++m]=line(0,point(0,0),point(mx,0));
                sort(lb+1,lb+m+1);
                int las=m;
                m=0;
                for(int j=1;j<=las;++j)
                    if(fabs(lb[j].ag-lb[j-1].ag)>eps) lb[++m]=lb[j];
                ll=1,q[rr=1]=lb[1];
                for(int j=2;j<=m;++j)
                {
                    while(ll<rr&&((lb[j].y-lb[j].x)^(jiao(q[rr],q[rr-1])-lb[j].x))<eps) --rr;
                    while(ll<rr&&((lb[j].y-lb[j].x)^(jiao(q[ll],q[ll+1])-lb[j].x))<eps) ++ll;
                    q[++rr]=lb[j];
                }
                while(ll<rr&&((q[ll].y-q[ll].x)^(jiao(q[rr],q[rr-1])-q[ll].x))<eps) --rr;
                for(int j=ll;j<=rr;++j) add(i,q[j].ii);
            }
            int sta=0;
            db ma=1e17;
            for(int i=1;i<=n;++i)
                if(ma>=dis(point(sx,sy),a[i]))
                    ma=dis(point(sx,sy),a[i]),sta=i;
            queue<int> qq;
            memset(di,0x3f3f3f,sizeof(di));
            di[sta]=0,v[sta]=1,qq.push(sta);
            while(!qq.empty())
            {
                int x=qq.front();
                qq.pop();
                v[x]=0;
                for(int i=hd[x];i;i=nt[i])
                {
                    int y=to[i];
                    if(di[y]>di[x]+1)
                    {
                        di[y]=di[x]+1;
                        if(!v[y]) v[y]=1,qq.push(y);
                    }
                }
            }
            printf("%d
    ",di[0]);
        }
        return 0; 
    }
    
  • 相关阅读:
    swift 第三方库迁移错误解决“Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choo
    ios 绘制虚线 CGContextSetLineDash的使用
    在 cell 中获取 textFlied内容的使用
    swift 委托代理传值
    swift3.0基础语法
    webSocket开源框架:SocketRocket 简单的使用
    iOS开发— Socket编程
    常见的 HTTP错误代码大全
    lambda表达式的使用
    浅谈静态代理模式 01
  • 原文地址:https://www.cnblogs.com/smyjr/p/10659665.html
Copyright © 2011-2022 走看看