最短路+线段交 POJ 1556 好题

  1 // 最短路+线段交 POJ 1556 好题
  2 // 题意:从(0,5)到(10,5)的最短距离,中间有n堵墙,每堵上有两扇门可以通过
  3 // 思路:先存图。直接n^2来暴力,不好写。分成三部分,起点 终点和之间的点:中间点之间:起点和终点的距离
  4 // n最大为18所以直接n^3最短路
  5
  6
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <map>
 12 #include <set>
 13 #include <queue>
 14 #include <stdlib.h>
 15 #include <cmath>
 16 using namespace std;
 17 typedef long long LL;
 18 const double inf = 1e9;
 19 const int N = 5000;
 20 const double eps = 1e-8;
 21 void fre() {freopen("in.txt","r",stdin);}
 22
 23 int sgn(double x){
 24     if(fabs(x)<eps) return  0;
 25     if(x<0) return -1;
 26     return 1;
 27 }
 28
 29 struct Point{
 30     double x,y;
 31     Point(){}
 32     Point(double _x,double _y){
 33         x=_x;y=_y;
 34     }
 35     Point operator -(const Point &b)const{
 36         return Point(x-b.x,y-b.y);
 37     }
 38     double operator *(const Point &b)const{
 39         return x*b.x+y*b.y;
 40     }
 41     double operator ^(const Point &b)const{
 42         return x*b.y-y*b.x;
 43     }
 44 };
 45
 46 struct Line{
 47     Point s,e;
 48     Line(){}
 49     Line(Point _s,Point _e){
 50         s=_s,e=_e;
 51     }
 52 };
 53 Line line[N];
 54 double xmult(Point p0,Point p1,Point p2){
 55     return (p1-p0)^(p2-p0);
 56 }
 57
 58 double dist(Point a,Point b){
 59     return sqrt((a-b)*(a-b));
 60 }
 61
 62 bool inter(Line l1,Line l2){
 63     return max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
 64 }
 65
 66 double d[100][100];
 67 int main(){
 68     // fre();
 69     int n;
 70     while(~scanf("%d",&n)){
 71         if(n==-1) break;
 72         // clc(d,
 73         for(int i=0;i<=4*n+1;i++){
 74             for(int j=0;j<=4*n+1;j++){
 75                 if(i==j) d[i][j]=0;
 76                 else d[i][j]=inf;
 77             }
 78         }
 79         for(int i=1;i<=n;i++){
 80             double x,y3,y1,y4,y2;
 81             scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
 82             line[i*2-1]=Line(Point(x,y1),Point(x,y2));
 83             line[i*2]=Line(Point(x,y3),Point(x,y4));
 84         }
 85         bool flag;
 86         for(int i=1;i<=4*n;i++){
 87             flag=true;
 88             int cn=(i+3)/4;
 89             Point tem;
 90             if(i&1) tem=line[(i+1)/2].s;
 91             else tem=line[(i+1)/2].e;
 92             for(int j=1;j<cn;j++){
 93                 if(inter(line[j*2-1],Line(Point(0,5),tem))==false&&inter(line[j*2],Line(Point(0,5),tem))==false){
 94                     flag=false;
 95                     break;
 96                 }
 97             }
 98             if(flag) d[0][i]=d[i][0]=dist(Point(0,5),tem);
 99             flag=true;
100             for(int j=cn+1;j<=n;j++){
101                 if(inter(line[j*2-1],Line(Point(10,5),tem))==false&&inter(line[j*2],Line(Point(10,5),tem))==false){
102                     flag=false;
103                     break;
104                 }
105             }
106             if(flag) d[4*n+1][i]=d[i][4*n+1]=dist(Point(10,5),tem);
107         }
108         flag=true;
109         for(int i=1;i<=4*n;i++){
110             for(int j=i+1;j<=4*n;j++){
111                flag=true;
112                Point p1,p2;
113                int cn1,cn2;
114                cn1=(i+3)/4;
115                cn2=(j+3)/4;
116                if(i&1) p1=line[(i+1)/2].s;
117                else p1=line[(i+1)/2].e;
118                if(j&1) p2=line[(j+1)/2].s;
119                else p2=line[(j+1)/2].e;
120                for(int cn=cn1+1;cn<cn2;cn++){
121                     if(inter(line[cn*2-1],Line(p1,p2))==false&&inter(line[cn*2],Line(p1,p2))==false){
122                       flag=false;
123                       break;
124                     }
125                }
126                if(flag) d[i][j]=d[j][i]=dist(p1,p2);
127             }
128         }
129         flag=true;
130         for(int i=1;i<=n;i++){
131             if(inter(line[i*2-1],Line(Point(0,5),Point(10,5)))==false&&inter(line[i*2],Line(Point(0,5),Point(10,5)))==false){
132                 flag=false;
133                 break;
134             }
135         }
136         if(flag) d[0][4*n+1]=d[4*n+1][0]=dist(Point(0,5),Point(10,5));
137         for(int i=0;i<=4*n+1;i++){
138             for(int j=0;j<=4*n+1;j++){
139                 for(int k=0;k<=4*n+1;k++){
140                     if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j];
141                 }
142             }
143         }
144         printf("%.2f\n",d[0][4*n+1]);
145     }
146     return 0;
147 }
时间: 2024-08-06 07:50:53

最短路+线段交 POJ 1556 好题的相关文章

POJ 1556 The Doors 线段交 dijkstra

LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个开口的两端点作为一个节点,再枚举点与点间能否直接到达(判相交),以此建图求最短路. /** @Date : 2017-07-11 16:17:31 * @FileName: POJ 1556 线段交+dijkstra 计算几何.cpp * @Platform: Windows * @Author :

POJ 1556 - The Doors 线段相交不含端点

POJ 1556 - The Doors题意:    在 10x10 的空间里有很多垂直的墙,不能穿墙,问你从(0,5) 到 (10,5)的最短距离是多少.    分析:        要么直达,要么一定是墙的边缘点之间以及起始点.终点的连线.        所以先枚举墙上每一点到其他点的直线可达距离,就是要判定该线段是否与墙相交(不含端点).        然后最短路. 1 #include <iostream> 2 #include <cstdio> 3 #include &l

Poj 1556 The Doors 计算几何+最短路

其实本题非常的无脑,无脑拍完1A,写到blog里只因为TM无脑拍也拍了很久啊= = #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdl

POJ 3304 Segments 基础线段交判断

LINK 题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点 思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交.判断相交先求叉积再用跨立定理.枚举每个线段的起始结束点作为直线起点终点遍历即可. /** @Date : 2017-07-12 14:35:44 * @FileName: POJ 3304 基础线段交判断.cpp * @Platform: Windows * @Author : Lweleth ([em

POJ 2653 线段交

思路: 运用队列存储没有被覆盖的木棍,没加入一个棍子,就要判断一下是否队列中的棍子被覆盖,如果被覆盖,就从队列中删除: 线段交判断方法:跨立实验 Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9698 Accepted: 3591 Description Stan has n sticks of various length. He throws them one at a time on th

poj 1556 zoj1721 BellmanFord 最短路+判断直线相交

http://poj.org/problem?id=1556 The Doors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6120   Accepted: 2455 Description You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will a

[转]POJ的刷题指南(加了超链接的)

网上看到的转过来一下,顺便把题目都加了个超链接,方便刷起~ POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: 一.基本算法:       (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.       (4)递推.       (5)构造法.(po

POJ 1556

枚举每两点的直线,看连线中是否存在线段交点,若存在,即这两点的直线不存在.建图,DIJK就可以了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 8 const int Max=100; 9 const int M=3000; 10 c

两边点连直线求交点总数 树状数组或线段树 poj 3067 Japan

http://poj.org/problem?id=3067 Japan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23602   Accepted: 6369 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island