zoukankan      html  css  js  c++  java
  • 线段判严格相交+最短路建图——poj1556

    /*
    两两枚举端点,如果线段不和任何一条线段相交,则连一条边,然后跑最短路 
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define N 205
    #define db double 
    
    const db eps=1e-6;
    int sign(db k){if(k>eps)return 1;else if(k<-eps)return -1;return 0;}
    int cmp(db k1,db k2){return sign(k1-k2);}
    
    struct point{
        db x,y;
        point(){}
        point(db _x,db _y):x(_x),y(_y){}
        point operator + (const point &k1) const {return point(x+k1.x,y+k1.y);}
        point operator - (const point &k1) const {return point(x-k1.x,y-k1.y);}
        db abs() {return sqrt(x*x+y*y);}
        db dis(point k1) {return (*this-k1).abs();}
    }; 
    db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    int checkSS(point k1,point k2,point k3,point k4){//判严格相交
        return sign(cross(k3-k1,k4-k1))*sign(cross(k3-k2,k4-k2))<0 &&
               sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<0;     
    }
    struct line{
        point p[2];
    };
    
    int n,totp,totl;
    point p[N];
    line l[N];
    int check(point k1,point k2){
        if(k1.dis(k2)==0)return 1;
        for(int i=1;i<=totl;i++)//不能有边和其相交 
            if(checkSS(k1,k2,l[i].p[0],l[i].p[1]))return 0;
        return 1;
    }
    
    struct Edge{
        int to,nxt;db w;
    }e[N*N*2];
    int head[N],tot;
    db mp[N][N];
    void init(){
        memset(head,-1,sizeof head);
        tot=0; 
    }
    void add(int u,int v,db w){
        e[tot].to=v;e[tot].nxt=head[u];e[tot].w=w;head[u]=tot++;
        mp[u][v]=mp[v][u]=1;
    }
    
    db dis[N];
    int vis[N];
    priority_queue<pair<db,int> >pq;
    void dijkstra(){
        memset(vis,0,sizeof vis);
        int s=0,t=totp;
        for(int i=0;i<=totp;i++)dis[i]=1e16;
        dis[s]=0;pq.push(make_pair(0,s));
        while(pq.size()){
            int now=pq.top().second;pq.pop();
            if(vis[now])continue;
            vis[now]=1;
            for(int i=head[now];i!=-1;i=e[i].nxt){
                int v=e[i].to;
                if(!vis[v] && dis[v]>dis[now]+e[i].w){
                    dis[v]=dis[now]+e[i].w;
                    pq.push(make_pair(-dis[v],v));
                }
            }
        }
        printf("%.2f
    ",dis[t]);
    }
    
    int main(){
        while(scanf("%d",&n) && n!=-1){
            init();totp=totl=0;
            
            p[totp++]=point(0,5);
            for(int i=1;i<=n;i++){
                db x;scanf("%lf",&x);
                point pp[6];
                for(int i=0;i<6;i++)pp[i].x=x;
                pp[0].y=0;pp[5].y=10;
                for(int i=1;i<=4;i++)scanf("%lf",&pp[i].y);
                for(int i=0;i<6;i++)p[totp++]=pp[i];
                for(int i=0;i<6;i+=2){
                    ++totl;
                    l[totl].p[0]=pp[i];
                    l[totl].p[1]=pp[i+1];
                }
            }
            p[totp]=point(10,5);
            /*
            for(int i=0;i<=totp;i++)cout<<p[i].x<<" "<<p[i].y<<'
    ';
            for(int i=1;i<=totl;i++){
                point k1=l[i].p[0],k2=l[i].p[1];
                cout<<k1.x<<" "<<k1.y<<' ';
                cout<<k2.x<<" "<<k2.y<<'
    ';
            }
            */
            for(int i=0;i<=totp;i++)
                for(int j=i+1;j<=totp;j++){
                    if(check(p[i],p[j])){
                        add(i,j,p[i].dis(p[j]));
                        add(j,i,p[i].dis(p[j]));
                    }
                }
            
            dijkstra();
        }
    } 
  • 相关阅读:
    阿狸的打字机(bzoj 2434)
    Censoring(bzoj 3940)
    文本生成器(bzoj 1030)
    病毒(bzoj 2938)
    Road(bzoj 2750)
    codevs 2370 小机房的树
    HDU 2838 Cow Sorting
    luogu P2253 好一个一中腰鼓!
    hdu 1166 敌兵布阵
    luogu P1901 发射站
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12322196.html
Copyright © 2011-2022 走看看