哦天哪这个萨比提又浪费了我好几个小时。
我们在check的时候只考虑严格相交就行了,想了很久才注意到这一点。
然后就建图跑最短路,over。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 #include <cstring> 7 #include <iomanip> 8 #include <iostream> 9 typedef double db; 10 using namespace std; 11 const db eps=1e-8; 12 const db pi=acos(-1); 13 int sign(db k){ 14 if (k>eps) return 1; else if (k<-eps) return -1; return 0; 15 } 16 int cmp(db k1,db k2){return sign(k1-k2);} 17 struct point{ 18 db x,y; 19 point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};} 20 point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} 21 point operator * (db k1) const{return (point){x*k1,y*k1};} 22 point operator / (db k1) const{return (point){x/k1,y/k1};} 23 db abs(){ return sqrt(x*x+y*y);} 24 db dis(point k1){ return(*this-k1).abs();} 25 }; 26 db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x; } 27 db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;} 28 int intersect(db l1,db r1,db l2,db r2){ 29 if (l1>r1) swap(l1,r1); if (l2>r2) swap(l2,r2); return cmp(r1,l2)!=-1&&cmp(r2,l1)!=-1; 30 } 31 int checkSS(point k1,point k2,point k3,point k4){ 32 return //intersect(k1.x,k2.x,k3.x,k4.x)&&intersect(k1.y,k2.y,k3.y,k4.y)&& 33 sign(cross(k3-k1,k4-k1))*sign(cross(k3-k2,k4-k2))<0&& 34 sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<0; 35 } 36 struct line{ 37 point p[2]; 38 }; 39 int checkSS(line a,line b){ 40 return checkSS(a.p[0],a.p[1],b.p[0],b.p[1]); 41 } 42 int n; 43 db dis[100010]; 44 struct node { //堆节点 45 int u;db d; 46 bool operator <(const node& rhs) const { 47 return d>rhs.d; 48 } 49 }; 50 struct Edge { int v,nxt;db w;}; 51 Edge e[500010]; 52 int head[100010],cnt=0; 53 void addEdge(int u,int v,db w) { 54 e[++cnt].v=v; 55 e[cnt].w=w; 56 e[cnt].nxt=head[u]; 57 head[u]=cnt; 58 } 59 void Dijkstra() { 60 for (int i=1;i<=10000;i++) dis[i]=10000; 61 dis[0]=0; 62 priority_queue<node> Q; //堆 63 Q.push((node){0,0}); 64 while (!Q.empty()) { 65 node fr=Q.top(); Q.pop(); 66 int u=fr.u;db d=fr.d; 67 if (cmp(d,dis[u])>0) continue; 68 for (int i=head[u];i;i=e[i].nxt) { 69 int v=e[i].v;db w=e[i].w; 70 if (cmp(dis[u]+w,dis[v])<0) { 71 dis[v]=dis[u]+w; 72 Q.push((node){v,dis[v]}); 73 } 74 } 75 } 76 } 77 db yl,y2,y3,y4,x; 78 vector<line> v; 79 vector<point> g; 80 bool check(line tmp){ 81 for(int i=0;i<v.size();i++){ 82 if(checkSS(tmp,v[i])){ 83 return false; 84 }//return false; 85 } 86 return true; 87 } 88 int main(){ 89 ios::sync_with_stdio(false); 90 cout<<fixed<<setprecision(2); 91 while (cin>>n&&n!=-1){ 92 g.push_back(point{0,5}); 93 for(int i=1;i<=n;i++){ 94 cin>>x>>yl>>y2>>y3>>y4; 95 g.push_back(point{x,yl}); 96 g.push_back(point{x,y2}); 97 g.push_back(point{x,y3}); 98 g.push_back(point{x,y4}); 99 v.push_back(line{point{x,0},point{x,yl}}); 100 v.push_back(line{point{x,y2},point{x,y3}}); 101 v.push_back(line{point{x,y4},point{x,10}}); 102 } 103 g.push_back(point{10,5}); 104 int m=g.size(); 105 for(int i=0;i<m;i++){ 106 for(int j=i+1;j<m;j++){ 107 if(check(line{g[i],g[j]})){ 108 //printf("%d %d ",i,j); 109 addEdge(i,j,g[i].dis(g[j])); 110 addEdge(j,i,g[i].dis(g[j])); 111 } 112 } 113 } 114 Dijkstra(); 115 cout<<dis[m-1]<<endl; 116 g.clear(); 117 v.clear(); 118 cnt=0; 119 memset(head,0, sizeof(head)); 120 } 121 } 122 /** 123 2 124 4 2 7 8 9 125 7 3 4.5 6 7 126 -1 127 */