九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11844521
代码1:
#include<iostream> #include<stdio.h> #include<string> #include<string.h> #include<algorithm> #include<map> #include<list> #include<set> #include<vector> #include<queue> #include<iomanip> #include<math.h> #define N 1050 #define ST 1001 #define EN 1002 #define M 10000 #define inf 1000000 #define eps 1e-8 #define ll long long using namespace std; inline ll Max(ll a,ll b){return a>b?a:b;} inline ll Min(ll a,ll b){return a<b?a:b;} struct Point{//点是2维的 double x,y; }; struct v{ Point Start,End; }; double Cross(Point p1,Point p2,Point p3,Point p4){//二维向量(p1p2)X(p3p4) 返回第三向量长度 double x1=p2.x-p1.x,y1=p2.y-p1.y; double x2=p4.x-p3.x,y2=p4.y-p3.y; return x1*y2-x2*y1; //为0表示 p1p2 与p3p4共线 //直线:不为0就是相交 } double Cross_v(v v1,v v2){ return Cross(v1.Start,v1.End,v2.Start,v2.End); } double point_dis(Point p1,Point p2){ return sqrt((double)((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); } bool On_Segment(Point p1,Point p2,Point p3){//p3点在 p1p2线段上 if(Cross(p1,p2,p1,p3)!=0)return false; bool iny=(p1.y<=p3.y && p3.y<=p2.y)||(p1.y>=p3.y && p3.y>=p2.y); bool inx=(p1.x<=p3.x && p3.x<=p2.x)||(p1.x>=p3.x && p3.x>=p2.x); if(inx && iny)return true; return false; } bool Segmentintersect(Point p1,Point p2,Point p3,Point p4){//p1p2 是否与 p3p4相交 double cross_1=Cross(p3,p4,p3,p1),cross_2=Cross(p3,p4,p3,p2);//cross_1 2必须一正一负且都不为0 double cross_3=Cross(p1,p2,p1,p3),cross_4=Cross(p1,p2,p1,p4);//cross_2 4必须一正一负且都不为0 //表示a线段 2点 在b线段 2侧 if(cross_1*cross_2<0 && cross_3*cross_4<0)return true; //a线段端点在 b线段上 视情况取舍这种位置 // if(cross_1==0 && On_Segment(p3,p4,p1))return true; // if(cross_2==0 && On_Segment(p3,p4,p2))return true; // if(cross_3==0 && On_Segment(p1,p2,p3))return true; // if(cross_4==0 && On_Segment(p1,p2,p4))return true; return false; } //----------------------- 2维计算几何模版------------------------------------- struct Edge{ int f,t,nex; double w; }edge[M]; int head[N],edgenum; int n; void addedge(int u,int v,double w){ Edge E={u,v,head[u],w}; edge[edgenum]=E; head[u]=edgenum++; } double dis[N]; void spfa(int s,int e){ queue<int>q; bool vis[N]; memset(vis,0,sizeof(vis)); int i,u,v; for(i=0;i<N;i++)dis[i]=inf; dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()){ u=q.front(); q.pop(); for(i=head[u];i!=-1;i=edge[i].nex) { v=edge[i].t; if(dis[v]>dis[u]+edge[i].w){ dis[v]=dis[u]+edge[i].w; if(!vis[v])q.push(v); } } } } Point line[N][4],Start,End; Point Seg[N][6]; int main() { int i,j; Start.x=0,Start.y=5; End.x=10,End.y=5; while(scanf("%d",&n),n>=0) { for(i=0;i<n;i++){ double x,y1,y2,y3,y4; scanf("%lf %lf%lf %lf%lf",&x,&y1,&y2,&y3,&y4); line[i][0].x=line[i][1].x=line[i][2].x=line[i][3].x=x; line[i][0].y=y1; line[i][1].y=y2; line[i][2].y=y3; line[i][3].y=y4; Seg[i][0].x=x,Seg[i][0].y=0; for(j=1;j<=4;j++)Seg[i][j]=line[i][j-1]; Seg[i][5].x=x,Seg[i][5].y=10; } memset(head,-1,sizeof(head)); edgenum=0; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) for(int ii=0;ii<4;ii++) for(int jj=0;jj<4;jj++) { bool can=true; for(int k=i+1;k<j && can;k++) for(int kk=0;kk<5 &&can;kk+=2) if(Segmentintersect(line[i][ii],line[j][jj],Seg[k][kk],Seg[k][kk+1])) can=false; if(can)addedge(i*10+ii,j*10+jj,point_dis(line[i][ii],line[j][jj])); } for(i=0;i<n;i++) for(int ii=0;ii<4;ii++) { bool cans=true,cane=true; for(int k=0;k<i && cans;k++) for(int kk=0;kk<5 &&cans;kk+=2) if(Segmentintersect(Start,line[i][ii],Seg[k][kk],Seg[k][kk+1])) cans=false; if(cans)addedge(ST,i*10+ii,point_dis(Start,line[i][ii])); for(int k=i+1;k<n && cane;k++) for(int kk=0;kk<5 &&cane;kk+=2) if(Segmentintersect(End,line[i][ii],Seg[k][kk],Seg[k][kk+1])) cane=false; if(cane)addedge(i*10+ii,EN,point_dis(End,line[i][ii])); } bool canse=true; for(int k=0;k<n && canse;k++) for(int kk=0;kk<5 &&canse;kk+=2) if(Segmentintersect(Start,End,Seg[k][kk],Seg[k][kk+1])) canse=false; if(canse)addedge(ST,EN,point_dis(Start,End)); spfa(ST,EN); printf("%.2lf\n",dis[EN]); } return 0; } /* 1 5 4 6 7 8 2 4 2 7 8 9 7 3 4.5 6 7 */
代码2:
#include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<math.h> #include<algorithm> #include<stdlib.h> #include<ctype.h> #include<iomanip> #include<set> #include<map> #include<list> #include<vector> #include<queue> #include<stack> using namespace std; const double pi=acos(-1.0); const double eps = 1e-8; int sgn(double x) { if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1; } struct Point { double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } double operator ^(const Point &b)const { return x*b.y - y*b.x; } double operator *(const Point &b)const { return x*b.x + y*b.y; } void transXY(double B) { double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); } }; double dis(Point a,Point b) { double ss=a.x-b.x; double tt=a.y-b.y; return sqrt(ss*ss+tt*tt); } struct Line { Point s,e; double k; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; k = atan2(e.y - s.y,e.x - s.x); } pair<int,Point> operator &(const Line &b)const { Point res = s; if(sgn((s-e)^(b.s-b.e)) == 0) { if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res); else return make_pair(1,res); } double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e)); res.x += (e.x-s.x)*t; res.y += (e.y-s.y)*t; return make_pair(2,res); } }; bool inter(Line l1,Line l2) { 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.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= 0 && sgn((l1.s-l2.s)^(l2.e-l1.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= 0; } struct NODE { double x,y1,y2,y3,y4; }pp[2000]; bool cmp(NODE a,NODE b) { return a.x<b.x; } #define inf 10000000 const int maxn=300010; int head[maxn],tol,m,n; double dist[maxn]; struct Edge { int to,next; double val; }edge[10*maxn]; void add(int u,int v,double w) { edge[tol].to=v; edge[tol].next=head[u]; edge[tol].val=w; head[u]=tol++; } struct Node { int id; double dist; Node(int a=0,double b=0):id(a),dist(b){} bool operator < (const Node &b) const { return dist>b.dist; } }; void fun(int st) { int i,j,u,v; priority_queue<Node> q; q.push(Node(st,0)); for(i=1;i<=n;i++)dist[i]=inf; dist[st]=0; while(!q.empty()) { Node ret=q.top();q.pop(); u=ret.id; if(dist[u]<ret.dist)continue; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(dist[v]>dist[u]+edge[i].val) { dist[v]=dist[u]+edge[i].val; q.push(Node(v,dist[v])); } } } } Line s1[500]; Point s2[500]; int main() { int i,j,k,m; while(~scanf("%d",&m)) { if(m==-1)break; for(i=1;i<=m;i++)scanf("%lf%lf%lf%lf%lf",&pp[i].x,&pp[i].y1,&pp[i].y2,&pp[i].y3,&pp[i].y4); sort(pp+1,pp+m+1,cmp); memset(head,-1,sizeof(head));tol=0;n=0; int indexx=0; s2[++n]=Point(0,5); for(i=1;i<=m;i++) { Point p1,p2,p3,p4,p5,p6; p1=Point(pp[i].x,0.0); s2[++n]=p1; p2=Point(pp[i].x,pp[i].y1); s2[++n]=p2; p3=Point(pp[i].x,pp[i].y2); s2[++n]=p3; p4=Point(pp[i].x,pp[i].y3); s2[++n]=p4; p5=Point(pp[i].x,pp[i].y4); s2[++n]=p5; p6=Point(pp[i].x,10.0); s2[++n]=p6; s1[++indexx]=Line(p1,p2); s1[++indexx]=Line(p3,p4); s1[++indexx]=Line(p5,p6); } s2[++n]=Point(10,5); for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { if(sgn(s2[i].x-s2[j].x)==0)continue; Line s(s2[i],s2[j]); int flag=1; for(k=1;k<=indexx;k++) { if(sgn(s1[k].s.x-s2[i].x)==0)continue; if(sgn(s1[k].s.x-s2[j].x)==0)continue; if(inter(s1[k],s)) { flag=0; break; } } if(flag) add(i,j,dis(s2[i],s2[j])); } } fun(1); printf("%.2f\n",dist[n]); } return 0; }