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 }
浙公网安备 33010602011771号