[vijos1013] 强墙 /[uva393] 房间最短路问题

来源:互联网 发布:淘宝网买盗版课程 编辑:程序博客网 时间:2024/04/28 23:13

题目描述

在一个长宽均为10,入口出口分别为(0,5)、(10,5)的房间里,有几堵墙,每堵墙上有两个缺口,求入口到出口的最短路经。
这里写图片描述


输入格式

第一排为n(n<=20),墙的数目。
接下来n排,每排5个实数x,a1,b1,a2,b2。
x表示墙的横坐标(所有墙都是竖直的),a1-b1和a2-b2之间为空缺。
a1、b1、a2、b2保持递增,x1-xn也是递增的。


输出格式

输出最短距离,保留2位小数。


样例数据

样例输入

2
4 2 7 8 9
7 3 4.5 6 7

样例输出

10.06


题目分析

比较难建图的一道题
先把所有墙建成线段,将墙的两端作为结点建图,在图中所有结点间建边(但是边不能与墙相交),边权为欧几里德距离
然后跑一次dijkstra就可以了
代码写的有点智障


源代码

#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() {    int num=0,bj=1;    char x=getchar();    while(x<'0'||x>'9') {        if(x=='-')bj=-1;        x=getchar();    }    while(x>='0'&&x<='9') {        num=num*10+x-'0';        x=getchar();    }    return num*bj;}struct Point {    double x,y;};double Dist(Point a,Point b) {    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}struct Vector {    double x,y;};Vector operator - (Point a,Point b) {    Vector c;    c.x=b.x-a.x;    c.y=b.y-a.y;    return c;}double Cross(Vector a,Vector b) { //叉积    return a.x*b.y-b.x*a.y;}bool Segment_Intersect(Point A,Point B,Point C,Point D) { //判断两线段是否相交    return (Cross((C-A),(D-A))*Cross((C-B),(D-B))<0)&&(Cross((A-C),(B-C))*Cross((A-D),(B-D))<0);}///////////////const int maxn=20005; //数组范围struct Edge { //前向星    int from,to;    double dist;};struct HeapNode {    double d;    int u; //u为当前结点    bool operator < (HeapNode a) const {        return d>a.d;    }};struct Dijkstra {    int n,m;    vector<Edge> edges; //邻接表    vector<int> G[maxn]; //记录每个结点可以到达的结点    bool vst[maxn];    double dist[maxn];    int path[maxn]; //使用path记录最短路    void init(int n) {        this->n=n;        for(int i=1; i<=n; i++)G[i].clear();        edges.clear();    }    void AddEdge(int from,int to,double dist) {        edges.push_back((Edge) {            from,to,dist        });        m=edges.size();        G[from].push_back(m-1);    }    void main(int s) { //核心算法        priority_queue<HeapNode> Q;        for(int i=1; i<=n; i++)dist[i]=1e10;        dist[s]=0;        path[s]=s;        memset(vst,0,sizeof(vst));        Q.push((HeapNode) {            0,s        });        while(!Q.empty()) {            HeapNode Now=Q.top();            Q.pop();            if(vst[Now.u])continue;            vst[Now.u]=1;            for(int i=0; i<G[Now.u].size(); i++) {                Edge& e=edges[G[Now.u][i]]; //边的信息                int Next=e.to;                if(dist[Next]>dist[Now.u]+e.dist) {                    dist[Next]=dist[Now.u]+e.dist;                    path[Next]=Now.u;                    Q.push((HeapNode) {                        dist[Next],Next                    });                }            }        }    }} ;/////////////// Point Start[105],End[105],P[105]; //障碍Dijkstra dij;int n,cnt=0,cnt1=0;int main() {    scanf("%d",&n);    P[++cnt1]=(Point) {        0,5    };    P[++cnt1]=(Point) {        10,5    };    for(int i=1; i<=n; i++) {        double x,a1,b1,a2,b2;        scanf("%lf%lf%lf%lf%lf",&x,&a1,&b1,&a2,&b2);        Start[++cnt].x=x;        Start[cnt].y=0;        End[cnt].x=x;        End[cnt].y=a1;        Start[++cnt].x=x;        Start[cnt].y=b1;        End[cnt].x=x;        End[cnt].y=a2;        Start[++cnt].x=x;        Start[cnt].y=b2;        End[cnt].x=x;        End[cnt].y=10;        P[++cnt1]= (Point) {            x,a1        };        P[++cnt1]= (Point) {            x,b1        };        P[++cnt1]= (Point) {            x,a2        };        P[++cnt1]= (Point) {            x,b2        };    }    dij.init(cnt1);    for(int i=1; i<=cnt1; i++)        for(int j=i+1; j<=cnt1; j++) {            int bj=1;            for(int k=1; k<=cnt; k++)                if(Segment_Intersect(P[i],P[j],Start[k],End[k])) {                    bj=0;                    break;                }            if(bj==0)continue;            dij.AddEdge(i,j,Dist(P[i],P[j]));            dij.AddEdge(j,i,Dist(P[i],P[j]));        }    dij.main(1);    printf("%0.2lf\n",dij.dist[2]);    return 0;}

0 0
原创粉丝点击