线段判相交+最短路建图——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\n",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<<'\n';
        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<<'\n';
        }
        */
        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();
    }
} 

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12322196.html