POJ 1556 The Doors(建图+最短路)

蒻苣:弱弱很弱,路过的巨巨还不吝赐教!^.^...QAQ

题意:给你n<18堵墙,每个墙输入五个点,有两扇门,求从(0,5)->(10,5)的最短路

题解:枚举每个点,到其它点不与直线相交的边(也就是构图),然而最短路一发即可.

代码:

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <cmath>
  8 using namespace std;
  9 const double INF  = 1E200;
 10 const double wc = 1E-8;
 11 struct POINT{
 12         double x,y;
 13         POINT( double a = 0,double b = 0 )  { x = a; y = b; }
 14 };
 15 POINT t[10000];
 16 struct LINESEG{
 17         POINT e;
 18         POINT s;
 19         LINESEG( POINT x,POINT y ) { e = x; s = y; }
 20         LINESEG(){}
 21 };
 22 LINESEG L[1000];
 23 double dist(POINT p1,POINT p2)                // 返回两点之间欧氏距离
 24 {
 25  return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
 26 }
 27 double multiply(POINT sp,POINT ep,POINT op)
 28 {
 29  return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
 30 }
 31 bool online(LINESEG l,POINT p)
 32 {
 33  return( (multiply(l.e,p,l.s)==0) &&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) );
 34 }
 35 bool intersect(LINESEG u,LINESEG v)
 36 {
 37  return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&&                     //排斥实验
 38    (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
 39    (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
 40    (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
 41    (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=wc)&&         //跨立实验
 42    (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=wc));
 43 }
 44 //  (线段u和v相交)&&(交点不是双方的端点) 时返回true
 45 bool intersect_A(LINESEG u,LINESEG v)
 46 {
 47  return ((intersect(u,v))&&
 48    (!online(u,v.s))&&
 49    (!online(u,v.e))&&
 50    (!online(v,u.e))&&
 51    (!online(v,u.s)));
 52 }
 53 bool intersect_l(LINESEG u,LINESEG v)
 54 {
 55  return multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=wc;
 56 }
 57 //----------------
 58 //使用优先队列优化:时间复杂度为O(E*logE),E为定点个数
 59 //
 60 //注意对vector<Edge>E[MAXN]进行初始化加边
 61 //
 62 //------------------
 63 const int MAXN = 10010;
 64 struct qnode
 65 {
 66     int v;
 67     double c;
 68     qnode(int _v=0,double _c=0):v(_v),c(_c){}
 69         bool operator <(const qnode &r) const
 70         {
 71             return c>=r.c;
 72         }
 73 };
 74 
 75 struct Edge
 76 {
 77     int v;
 78     double cost;
 79     Edge (int _v=0,double _cost = 0):v(_v),cost(_cost){}
 80 };
 81 vector<Edge>E[MAXN];
 82 bool vis[MAXN];
 83 double dis[MAXN];
 84 void Dijkstra(int n,int start)
 85 {
 86     memset(vis,false,sizeof(vis));
 87     for(int i = 1; i <= n;i++) dis[i] = INF;
 88     priority_queue<qnode>que;
 89     while(!que.empty()) que.pop();
 90     dis[start] = 0;
 91     que.push(qnode(start,0));
 92     qnode tmp;
 93     while(!que.empty())
 94     {
 95         tmp = que.top();
 96         que.pop();
 97         int u = tmp.v;
 98         if(vis[u])continue;
 99             vis[u] = true;
100             for(int i = 0    ;i<E[u].size();i++)
101             {
102                 int v = E[tmp.v][i].v;
103                 double cost = E[u][i].cost;
104                 if(!vis[v] && dis[v]>(dis[u]+cost)+wc)
105                     {
106                         dis[v] = dis[u] + cost;
107                         que.push(qnode(v,dis[v]));
108                     }
109             }
110     }
111 }
112 
113 void addedge(int u,int v,double w)
114 {
115     E[u].push_back(Edge(v,w));
116 }
117 int main()
118 {
119         int n;
120         while(cin>>n)
121         {
122                 //memset(dis,0,sizeof(dis));
123                 memset(E,0,sizeof(E));
124                 //memset(vis,0,sizeof(vis));
125                 memset(t,0,sizeof(t));
126                 memset(L,0,sizeof(L));
127                 if(n==-1)break;
128                // if(!n) {puts("10");continue;}
129                 double aa,bb,cc,dd,ee;
130                 int j = 0;
131                 int ans=1;
132                 t[ans].x=0;
133                 t[ans++].y=5;
134                 for(int i = 1;i <= n;i ++)
135                 {
136                         scanf("%lf%lf%lf%lf%lf",&aa,&bb,&cc,&dd,&ee);
137                         L[j].e.x=aa; L[j].e.y=0;L[j].s.x=aa; L[j].s.y=bb;
138                         t[ans]=L[j].s;ans++;j++;
139                         L[j].e.x=aa; L[j].e.y=cc;
140                         t[ans]=L[j].e;ans++;
141                         L[j].s.x=aa; L[j].s.y=dd;
142                         t[ans++]=L[j].s;j++;
143                         L[j].e.x=aa; L[j].e.y=ee;
144                         t[ans++]=L[j].e;
145                         L[j].s.x=aa; L[j++].s.y=10;
146 
147                 }
148                 t[ans].x=10;t[ans].y=5;
149                 POINT a ;POINT b ;
150                 //4*n+2个点
151                 int len = j;
152                 for(int i = 1;i <= ans; i++)//枚举每一个点
153                 {
154                         for(int  jj = i+1;jj <= ans;jj++)
155                         {
156                                 if(jj!=i)
157                                 {
158                                         LINESEG l;
159                                         l.e = t[i];l.s=t[jj];
160                                         int flag = 1;
161                                         for(int k = 0;k<len;k++)
162                                         {
163                                                 /*POINT aaa = L[k].e;
164                                                 POINT bbb = L[k].s;
165                                                 if(dist(aaa,t[i])==0||dist(aaa,t[jj])==0||dist(bbb,t[i])==0||dist(bbb,t[jj])==0)
166                                                         ;
167                                                 else*/
168                                                 if(intersect_A(L[k],l))
169                                                 {
170                                                         if(i==1) {//cout<<jj<<" "<<k<<endl;
171                                                        // cout<<L[k].e.x<<" "<<L[k].e.y<<endl;
172                                                        // cout<<L[k].s.x<<" "<<L[k].s.y<<endl;
173                                                         }
174                                                         flag = 0;break;
175                                                 }
176                                         }
177                                         double w = dist(t[i],t[jj]);
178                                         if(flag) {addedge(i,jj,w); //cout<<i<<" "<<jj<<endl;
179                                         }
180                                 }
181                         }
182                 }
183                 Dijkstra(ans,1);
184                 printf("%.2f\n",dis[ans]);
185         }
186 }
View Code

 

posted on 2015-08-21 23:09  小松song  阅读(99)  评论(0)    收藏  举报

导航