poj 1066 计算几何构图+最短路

来源:互联网 发布:好听的编程项目名称 编辑:程序博客网 时间:2024/06/09 17:32

代码估计不用看了。。。。太长了,烦!纯粹是为了纪念一下我的三个多小时。。。。。。

说下怎么做好了,先用几何关系算出所有交点,然后根据交点求出所有可能的门(也就是同一条线上相邻两个交点点的中点),然后算一下门的关系,就是哪两个门是相邻的,最后,要求最短路,你懂的

#include<stdio.h>#include<string.h>#include<math.h>#include<vector>#include<queue>#include<algorithm>#define eps 1e-5#define val 600#define zero(x) (((x)>0?(x):-(x))<eps)using namespace std;typedef struct node {double x,y;int no;}point;typedef struct vode{point a,b;}line;typedef struct qode{int l, step;}position;bool map[val][val];bool vis[val];vector<point> data[val];vector<line> LN;vector<point> in;int n,t;int solve();point end;point intersection(line u,line v);int intersect_ex(line u,line v);int intersect_in(line u,line v);int same_side(point p1,point p2,line l);int dot_online_in(point p,line l);int opposite_side(point p1,point p2,line l);int dots_inline(point p1,point p2,point p3);double xmult(point p1,point p2,point p0);bool lessx(const point &s1,const point &s2){if(!zero(s1.x-s2.x)) return s1.x<s2.x;else return s1.y<s2.y;}int main(){int ans,i,j;line p;point h,m;while(scanf("%d",&n)!=EOF){LN.clear();in.clear();for(i=0;i<n+4;i++) data[i].clear();p.a.x=0,p.a.y=0;p.b.x=0,p.b.y=100;LN.push_back(p);p.b.x=100,p.b.y=0;LN.push_back(p);p.a.x=100,p.a.y=0;p.b.x=100,p.b.y=100;LN.push_back(p);p.a.x=0,p.a.y=100;LN.push_back(p);for(i=4;i<n+4;i++){scanf("%lf %lf %lf %lf",&p.a.x,&p.a.y,&p.b.x,&p.b.y);LN.push_back(p);}n+=4;/*for(i=0;i<n;i++)printf("(%.2lf,%.2lf)   (%.2lf,%.2lf) \n",LN[i].a.x,LN[i].a.y,LN[i].b.x,LN[i].b.y);*/scanf("%lf %lf",&end.x,&end.y);ans=solve();printf("Number of doors = %d\n",ans);}return 0;}int solve(){int bfs(int );int i,j,k,cnt=0,num;point sme,next;line L;in.clear();memset(map,false,sizeof(map));for(i=0;i<n;i++)//先来找出交点for(j=i+1;j<n;j++){//printf("I:%d   j:%d    ",i,j-4);if(intersect_in(LN[i],LN[j])){//printf("FIND!");sme=intersection(LN[i],LN[j]);data[i].push_back(sme);data[j].push_back(sme);}//putchar('\n');}//printf("check:%d (%.2lf,%.2lf)   (%.2lf,%.2lf) \n",intersect_in(LN[0],LN[6]),LN[6].a.x,LN[6].a.y,LN[6].b.x,LN[6].b.y);for(i=0;i<n;i++)sort(data[i].begin(),data[i].end(),lessx);for(i=0;i<n;i++){for(j=0;j<data[i].size()-1;j++){sme=data[i][j];sme.no=cnt++;next=data[i][j+1];sme.x=(sme.x+next.x)/2;sme.y=(sme.y+next.y)/2;in.push_back(sme);}}/*for(i=0;i<n;i++){for(j=0;j<data[i].size();j++)printf("(%.2lf %.2lf)  ",data[i][j].x,data[i][j].y);   putchar('\n');}*//*for(i=0;i<in.size();i++)printf("(%.2lf %.2lf) \n",in[i].x,in[i].y);*/end.no=cnt++;in.push_back(end);for(i=0;i<in.size();i++)for(j=i+1;j<in.size();j++){L.a=in[i],L.b=in[j];for(k=0;k<n;k++){if(intersect_in(L,LN[k]))if(!dots_inline(in[i],LN[k].a,LN[k].b)&&!dots_inline(in[j],LN[k].a,LN[k].b))break;}if(k>=n){//if(in[i].no==25) printf("J:%d\n",j);map[in[i].no][in[j].no]=map[in[j].no][in[i].no]=true;}}/*for(i=0;i<cnt;i++){for(j=0;j<cnt;j++){printf("%d ",map[i][j]);}putchar('\n');}*/num=bfs(cnt);return num;}int bfs(int cnt){int i;queue<position>q;cnt--;position now,next;now.l=cnt;now.step=0;q.push(now);memset(vis,false,sizeof(vis));while(!q.empty()){now=q.front();//printf("NOW: %d  (%.2lf,%.2lf)   \n",now.l,in[now.l].x,in[now.l].y);if(zero(in[now.l].x)||zero(in[now.l].y)||zero(in[now.l].x-100)||zero(in[now.l].y-100)) {//printf("FFFFFFFFFFINF!\n");return now.step;}q.pop();next.step=now.step+1;for(i=0;i<=cnt;i++){if(vis[i]) continue;next.l=i;if(map[now.l][i]) {q.push(next);vis[i]=true;}}}return 1111111;}point intersection(line u,line v){point ret=u.a;double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));ret.x+=(u.b.x-u.a.x)*t;ret.y+=(u.b.y-u.a.y)*t;return ret;}int intersect_ex(line u,line v){return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);}int intersect_in(line u,line v){if (!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);}int same_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;}int dot_online_in(point p,line l){return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;}int opposite_side(point p1,point p2,line l){return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;}int dots_inline(point p1,point p2,point p3){return zero(xmult(p1,p2,p3));}double xmult(point p1,point p2,point p0){return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}