zoukankan      html  css  js  c++  java
  • poj 1556 The door

    题目链接:http://poj.org/problem?id=1556

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int maxn = 1000;
    const int maxe = 20000;
    const int INF = 0x3f3f3f;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    
    struct Point{
        double x,y;
        Point(double x=0, double y=0) : x(x),y(y){ }    //构造函数
    };
    typedef Point Vector;
    
    Vector operator + (Vector A , Vector B){return Vector(A.x+B.x,A.y+B.y);}
    Vector operator - (Vector A , Vector B){return Vector(A.x-B.x,A.y-B.y);}
    Vector operator * (Vector A , double p){return Vector(A.x*p,A.y*p);}
    Vector operator / (Vector A , double p){return Vector(A.x/p,A.y/p);}
    
    bool operator < (const Point& a,const Point& b){
        return a.x < b.x ||( a.x == b.x && a.y < b.y);
    }
    
    int dcmp(double x){
        if(fabs(x) < eps) return 0;
        else              return x < 0 ? -1 : 1;
    }
    bool operator == (const Point& a, const Point& b){
        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    
    ///向量(x,y)的极角用atan2(y,x);
    double Dot(Vector A, Vector B){ return A.x*B.x + A.y*B.y; }
    double Length(Vector A)    { return sqrt(Dot(A,A)); }
    double Angle(Vector A, Vector B)  { return acos(Dot(A,B) / Length(A) / Length(B)); }
    
    double Cross(Vector A, Vector B)  { return A.x*B.y - A.y * B.x; }
    double Area2(Point A,Point B,Point C) { return Cross(B-A,C-A); }
    
    
    bool SegmentIntersection(Point a1, Point a2, Point b1, Point b2) {
        bool flag = max(a1.x, a2.x) >= min(b1.x, b2.x) && max(b1.x, b2.x) >= min(a1.x, a2.x) &&
                    max(a1.y, a2.y) >= min(b1.y, b2.y) && max(b1.y, b2.y) >= min(a1.y, a2.y);
        double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
               c3 = Cross(b2-b1,a1-b1), c4 = Cross(b2-b1,a2-b1);
        return flag && dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
    }
    
    bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){
        double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
               c3 = Cross(b2-b1,a1-b1), c4 = Cross(b2-b1,a2-b1);
        return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
    }
    
    struct Edge{
        int u,v;
        double w;
        int next;
        void assign(int u_,int v_,double w_,int next_){
            u = u_;  v = v_;  w = w_;  next = next_;
        }
        bool operator < (const Edge& r) const{
             return  w > r.w;
        }
    }edges[maxe];
    
    struct Dijkstra{
        int s,t;
        int head[maxn];
        int cnt;
        double d[maxn];
    
        void addedge(int u,int v,double w){
            edges[cnt].assign(u,v,w,head[u]);
            head[u] = cnt++;
        }
    
        void init(int s_,int t_){
            s = s_;   t = t_;
            cnt = 0;
            memset(head,-1,sizeof(head));
        }
    
        double dijkstra(){
            priority_queue<Edge> Q;
            while(!Q.empty())  Q.pop();
            for(int i=1;i<=maxn;i++)  d[i] = INF;
            bool vis[maxn];
            memset(vis,0,sizeof(vis));
            Edge edge = {s,0,0};
            Q.push(edge);  d[s] = 0;
            while(!Q.empty()){
                Edge e = Q.top() ; Q.pop() ;
                int u = e.u;
                if(vis[u]) continue;
                vis[u] = true;
                for(int i=head[u];i!=-1;i=edges[i].next){
                    int v = edges[i].v;
                    if( d[v] > d[u] + edges[i].w){
                        d[v] = d[u] + edges[i].w;
                        Edge edge = {v,0,d[v]};
                        Q.push(edge);
                    }
                }
            }
            return d[t];
        }
    };
    
    /************************分割线****************************/
    
    Point P[maxn][4];
    int n;
    Dijkstra solver;
    int main()
    {
        //freopen("E:\acm\input.txt","r",stdin);
    
        while(cin>>n && n != -1){
            solver.init(1,4*n+2);
            P[0][0] =Point(0,5);   P[n+1][0] =Point(10,5);
            for(int i=1;i<=n;i++){
                double x,y;
                scanf("%lf",&x);
                for(int j=0;j<=3;j++){
                 scanf("%lf",&y);
                 P[i][j]=Point(x,y);
               }
            }
    
            for(int i=0;i<=n;i++){
                if(i==0){
                    for(int j=i+1;j<=n;j++)
                       for(int k=0;k<=3;k++){
                           int flag = true;
                           for(int m=1;m<=j-1;m++){
                              Point a1=P[m][0],a2=P[m][1],b1=P[m][2],b2=P[m][3];
                              if(!SegmentIntersection(P[0][0],P[j][k],a1,a2) && !SegmentIntersection(P[0][0],P[j][k],b1,b2)){
                                  flag = false;   break;
                              }
                           }
                           if(flag){
                              solver.addedge(1,4*j+k-2,Length(P[0][0]-P[j][k]));
                           }
                       }
                   int flag = true;
                   for(int m=1;m<=n;m++){
                      Point a1=P[m][0],a2=P[m][1],b1=P[m][2],b2=P[m][3];
                      if(!SegmentIntersection(P[0][0],P[n+1][0],a1,a2) && !SegmentIntersection(P[0][0],P[n+1][0],b1,b2)){
                          flag = false;   break;
                      }
                   }
                   if(flag){
                      solver.addedge(1,4*n+2,Length(P[0][0]-P[n+1][0]));
                   }
    
                }
                else{
                   for(int h=0;h<=3;h++){  //确定点P[i][h]
                       for(int j=i+1;j<=n;j++)
                       for(int k=0;k<=3;k++){   //确定点p[j][k];
                           int flag = true;
                           for(int m=i+1;m<=j-1;m++){
                              Point a1=P[m][0],a2=P[m][1],b1=P[m][2],b2=P[m][3];
                              if(!SegmentIntersection(P[i][h],P[j][k],a1,a2)&&!SegmentIntersection(P[i][h],P[j][k],b1,b2)){
                                  flag = false;   break;
                              }
                           }
                           if(flag){
                              solver.addedge(4*i+h-2,4*j+k-2,Length(P[i][h]-P[j][k]));
                           }
                       }
                       int flag = true;
                       for(int m=i+1;m<=n;m++){
                          Point a1=P[m][0],a2=P[m][1],b1=P[m][2],b2=P[m][3];
                          if(!SegmentIntersection(P[i][h],P[n+1][0],a1,a2)&&!SegmentIntersection(P[i][h],P[n+1][0],b1,b2)){
                              flag = false;   break;
                          }
                       }
                       if(flag){
                          solver.addedge(4*i+h-2,4*n+2,Length(P[i][h]-P[n+1][0]));
                       }
                   }
                }
            }
            printf("%.2f
    ",solver.dijkstra());
        }
    }
    View Code
  • 相关阅读:
    Oracle EBS 初始化用户密码
    Oracle EBS FND User Info API
    linux ERROR: ld.so: object '/lib/libcwait.so' from /etc/ld.so.preload cannot be preloaded: ignored.
    linux解压cpio.gz类型文件
    linux删除乱码文件
    linux使用man命令后退出
    linux字符图形界面
    Red Hat linux 如何增加swap空间
    Linux删除文件夹命令
    Linux本地无法登录,远程却可以登录
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3251697.html
Copyright © 2011-2022 走看看