//這道題就是麻煩了點,其他都很簡單,細節問題。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define PR 1e-8
#define N 10005
double edge[N][N];
double dis[N];
bool vis[N];
struct TPoint
{
double x,y;
TPoint(){}
TPoint(double _x,double _y):x(_x),y(_y){}
TPoint operator-(const TPoint p) {return TPoint(x-p.x,y-p.y);}
};
struct TSeg
{
TPoint st[2];
TSeg(){}
TSeg(TPoint a,TPoint b){st[0]=a,st[1]=b;}
}g;
struct TDoor
{
TSeg d[2];
}door[N];
int n,m;
int dblcmp(double a) {return fabs(a)<PR?0:a>0?1:-1;}
double cross(TPoint a,TPoint b,TPoint c)
{
TPoint s(b-a),t(c-a);
return s.x*t.y-s.y*t.x;
}
double dot(TPoint a,TPoint b,TPoint c)
{
TPoint s(b-a),t(c-a);
return s.x*t.x+s.y*t.y;
}
int betweencmp(TPoint a,TPoint b,TPoint c)
{
return dblcmp(dot(a,b,c));
}
double dist(TPoint a,TPoint b)
{
TPoint s(b-a);
return sqrt(s.x*s.x+s.y*s.y);
}
bool segcross(TSeg a,TSeg b)//線段判交
{
double s1,s2,s3,s4;
int d1,d2,d3,d4,l=0;
d1=dblcmp(s1=cross(a.st[0],b.st[0],b.st[1]));//叉積
d2=dblcmp(s2=cross(a.st[1],b.st[0],b.st[1]));
d3=dblcmp(s3=cross(b.st[0],a.st[0],a.st[1]));
d4=dblcmp(s4=cross(b.st[1],a.st[0],a.st[1]));
if((d1^d2)==-2&&(d3^d4)==-2)//標準相交,返回交點
return 1;
if(d3==0&&(betweencmp(a.st[0],b.st[0],b.st[1])<=0))//a.s在線b上
return 1;
if(d4==0&&(betweencmp(a.st[1],b.st[0],b.st[1])<=0))//a.e在線b上
return 1;
if(d1==0&&(betweencmp(b.st[0],a.st[0],a.st[1])<=0))//b.s在線a上
return 1;
if(d2==0&&(betweencmp(b.st[1],a.st[0],a.st[1])<=0))//b.e在線a上
return 1;
return 0;
}
void getedge()
{
int i,j,k,i1,i2,j1,j2;
bool tmp;
for(i=1;i<=n+1;i++)
for(j=0;j<i;j++)
for(i1=0;i1<2;i1++)
for(j1=0;j1<2;j1++)
for(i2=0;i2<2;i2++)
for(j2=0;j2<2;j2++)
{
tmp=false;
for(k=j+1;k<i;k++)
{
g.st[0]=door[j].d[j1].st[j2];
g.st[1]=door[i].d[i1].st[i2];
if(!(segcross(g,door[k].d[0]))
&&!(segcross(g,door[k].d[1])))
{tmp=true;break;}
}
if(!tmp)
if(j==0) edge[j][4*i-2*i1-i2]=dist(door[j].d[j1].st[j2],door[i].d[i1].st[i2]);
else edge[4*j-2*j1-j2][4*i-2*i1-i2]=dist(door[j].d[j1].st[j2],door[i].d[i1].st[i2]);
}
}
void dijkstra(int u,int v)
{
int i,j,k;
n=4*n+1;
for(i=0;i<=n;i++)
{
dis[i]=edge[u][i];
vis[i]=0;
}
vis[u]=1; dis[u]=0;
for(i=1;i<=n;i++)
{
int min=1e10;u=-1;
for(j=0;j<=n;j++)
{
if(!vis[j]&&dis[j]<min) {min=dis[j]; u=j;}
}
if(u==-1) break;
vis[u]=1;
for(j=0;j<=n;j++)
{
if(!vis[j]&&dis[u]+edge[u][j]<dis[j])
dis[j]=dis[u]+edge[u][j];
}
}
printf("%.2lf\n",dis[v]);
}
int main()
{
while(scanf("%d",&n),n!=-1)
{
int i,j,k;
double x,y1,y2;
door[0].d[0].st[0]=TPoint(0,5); door[0].d[0].st[1]=TPoint(0,5);
door[0].d[1].st[0]=TPoint(0,5); door[0].d[1].st[1]=TPoint(0,5);
for(i=1;i<=n;i++)
{
scanf("%lf%lf%lf",&x,&y1,&y2);
door[i].d[0].st[0]=TPoint(x,y1); door[i].d[0].st[1]=TPoint(x,y2);
scanf("%lf%lf",&y1,&y2);
door[i].d[1].st[0]=TPoint(x,y1); door[i].d[1].st[1]=TPoint(x,y2);
}
door[n+1].d[0].st[0]=TPoint(10,5); door[n+1].d[0].st[1]=TPoint(10,5);
door[n+1].d[1].st[0]=TPoint(10,5); door[n+1].d[1].st[1]=TPoint(10,5);
for(i=0;i<=4*n+4;i++) for(j=0;j<=4*n+4;j++) edge[i][j]=1e10;
getedge();
dijkstra(0,4*n+1);
}
return 0;
}
poj1556---計算幾何+最短路
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.