poj-1556 The Doors

本题通过主要是要明白最短路径必定是通过门边产生的如图

如上图,不会残生第三种情况,所以这道题就简单了,先求任意两直接可连线点间的距离,再通过dijkstra算法求出最短路即可。

两直接可连线点是指两线段可以之间连线,并且不存在其他线段在两点之间(可以端点相交)。两线段是否相交可以通过快速排斥实验和跨立实验完成,然后细心一点就好了。#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define INF 0x3f3f3f3f
#define max_dou 10000000;
using namespace std;
struct node{
    double x;
    double y1,y2,y3,y4;
};
struct point{
    double x,y;
};
point pt[75];
node wall[20];//代表每堵墙
double mp[18*4+2+1][75];
double d[75];
bool used[75];
int V;
void dijkstra(int s){
    fill(d+1,d+V+1,INF);
    fill(used+1,used+V+1,false);
    d[s]=0;
    while(true){
        int v=-1;
        for(int u=1;u<=V;u++){
            if(!used[u]&&(v==-1||d[u]<d[v])) v=u;
        }
        if(v==-1) break;
        used[v]=true;
        for(int u=1;u<=V;u++){
            d[u]=min(d[u],d[v]+mp[u][v]);
        }
    }
}
int pc(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){
    if(min(x1,x2)<=max(x3,x4)&&min(x3,x4)<=max(x1,x2)
       &&min(y1,y2)<=max(y3,y4)&&min(y3,y4)<=max(y1,y2))
        return 1;//不排斥
    else return 0;
}
int judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){
    if(((x1-x3)*(y4-y3)-(x4-x3)*(y1-y3))*((x4-x3)*(y2-y3)-(x2-x3)*(y4-y3))>0&&
       ((x3-x2)*(y1-y2)-(x1-x2)*(y3-y2))*((x1-x2)*(y4-y2)-(y1-y2)*(x4-x2))>0&&
       pc(x1,y1,x2,y2,x3,y3,x4,y4))
        return 0;//两线段相交
    else return 1;//两线段不相交
}
int main()
{
    int n;
    while(cin>>n&&n!=-1){
        V=4*n+2;
        memset(mp,INF,sizeof(mp));
        for(int i=0;i<=74;i++){
            for(int j=0;j<=74;j++){
                mp[i][j]=max_dou;
            }
        }
        for(int i=1;i<=n;i++){
            cin>>wall[i].x>>wall[i].y1>>wall[i].y2>>wall[i].y3>>wall[i].y4;
        }
        for(int i=0;i<n;i++){
            pt[4*i+2].x=wall[i+1].x,pt[4*i+2].y=wall[i+1].y1;
            pt[4*i+3].x=wall[i+1].x,pt[4*i+3].y=wall[i+1].y2;
            pt[4*i+4].x=wall[i+1].x,pt[4*i+4].y=wall[i+1].y3;
            pt[4*i+5].x=wall[i+1].x,pt[4*i+5].y=wall[i+1].y4;
        }
        pt[1].x=0,pt[1].y=5;
        pt[4*n+2].x=10,pt[4*n+2].y=5;
        for(int i=1;i<=4*n+2;i++){
            for(int j=i+1;j<=4*n+2;j++) {
                int d=0;
                for(int k=1;k<=n;k++){
                    if(judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,0,wall[k].x,wall[k].y1)&&
                    judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,wall[k].y2,wall[k].x,wall[k].y3)&&
                    judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,wall[k].y4,wall[k].x,10)){
                        d++;
                    }
                }
                if(d==n){
                    mp[i][j]=sqrt((pt[i].x-pt[j].x)*(pt[i].x-pt[j].x)+(pt[i].y-pt[j].y)*(pt[i].y-pt[j].y));
                    mp[j][i]=mp[i][j];
                }
            }
        }
        dijkstra(1);
        printf("%.2lf\n",d[4*n+2]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41641469/article/details/82954330