zoukankan      html  css  js  c++  java
  • BZOJ 1137: [POI2009]Wsp 岛屿

    Description

    一个凸多边形,任意两点间有连边,有一些边不能使用,求(1)到(n)最短距离,(nleqslant 10^5,mleqslant 10^6)。

    Solution

    半平面交.

    这个路是可以在交点拐上另一条路的..然后就成了几个半平面,按顺序加入可以直接用栈来维护了..

    Code

    /**************************************************************
        Problem: 1137
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:6604 ms
        Memory:74576 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    namespace CG {
        typedef double LD;
        const LD eps = 1e-8;
        #define sqr(x) ((x)*(x))
         
        int dcmp(LD x) { return fabs(x)<eps?0:(x>0?1:-1); }
        struct Point {
            LD x,y;
            Point(LD _x=0,LD _y=0) :x(_x),y(_y) { }
        };
        typedef Point Vector;
         
        Vector operator + (const Vector &a,const Vector &b) { return Vector(a.x+b.x,a.y+b.y); }
        Vector operator - (const Vector &a,const Vector &b) { return Vector(a.x-b.x,a.y-b.y); }
        Vector operator * (const Vector &a,const LD &b) { return Vector(a.x*b,a.y*b); }
         
        LD Cross(const Vector &a,const Vector &b) { return a.x*b.y-a.y*b.x; }
        LD get_a(const Vector &a) { return atan2(a.y,a.x); }
        LD dis(const Point &a,const Point &b) { return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); }
         
        struct Line {
            Point p;
            Vector v;
            LD ang;
            Line(Point _p=Point(),Vector _v=Vector()) :p(_p),v(_v) { ang=get_a(_v); }
            Point get_p(LD t) { return p+v*t; }
            int chkleft(Point pt) { return Cross(v,pt-p)>0; }
        };
        int cmpa(const Line &a,const Line &b) { return a.ang<b.ang; }
         
        Point get_l_l(Line a,Line b) {
            Vector u=a.p-b.p;
            LD t=Cross(b.v,u)/Cross(a.v,b.v);
            return a.get_p(t);
        }
    }
     
    using namespace CG;
     
    typedef pair<int,int> pr;
     
    const int N = 1e6+50;
    int n,m;
    Point p[N];
    vector<int> pp[N];
    vector<Line> ls;
    vector<Point> pt;
     
    int tp;
    Line stk[N];
    void insert(Line x) {
        while(tp>=2 && x.chkleft(get_l_l(stk[tp],stk[tp-1]))) tp--;
        stk[++tp]=x;
    }
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            p[i]=Point(u,v);
        }
        for(int i=1;i<=m;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            if(u>v) swap(u,v);
            pp[u].push_back(v);
        }
        for(int i=1,j,k,t=0;i<=n;i++) {
            sort(pp[i].begin(),pp[i].end(),greater<int>());
            for(j=n,k=0;k<(int)pp[i].size() && j>t;k++,j--) if(pp[i][k]!=j) break;
            if(j>t) insert(Line(p[i],Point(p[t=j]-p[i])));
        }
        double ans=0;
        Point lt=p[1],tmp;
        for(int i=2;i<=tp;i++) tmp=get_l_l(stk[i-1],stk[i]),ans+=dis(lt,tmp),lt=tmp;
        ans+=dis(lt,p[n]);
        printf("%.8lf
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    Java Web(5) Spring 下使用Junit4 单元测试
    聊聊单元测试(三)——Spring Test+JUnit完美组合
    浅谈ELK日志分析平台
    ELK 实现 Java 分布式系统日志分析架构
    ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台
    开源分布式搜索平台ELK(Elasticsearch+Logstash+Kibana)入门学习资源索引
    自动补全下拉框(可输入匹配的下拉框)
    这是一篇满载真诚的微信小程序开发干货
    微服务化的多组件项目,跨地域、分布式版本管理和发布方式
    解放双手,发掘更大的价值:智能化运维
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6721302.html
Copyright © 2011-2022 走看看