http://poj.org/problem?id=1556
这道题目是一道图论和计算几何结合的题目,算是比较好的一道题目。
做这样的题目能够很好的理解计算几何模板的重要性,题目不是很难,主要是怎样将题目中的关键部分给分析出来,这方面我还是应该多加练习。我是用模板套的,比较好理
解,具体见代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1e-8
#define inf 10000000
const int maxn=120;
//定义点
struct point
{
double x,y;
}s[maxn];
//定义线段
struct Seg
{
point a,b;
}seg[maxn];
double cost[maxn][maxn];
//重载最大值、最小值计算函数
double min(double x,double y)
{return x<y?x:y;}
double max(double x,double y)
{return x>y?x:y;}
//判断double型的正数、负数和0,分别相应的返回1、-1和0
int dblcmp(double x)
{
if(x==0) return 0;
return (x>0)?1:-1;
}
//计算叉积
double det(double x1,double y1,double x2,double y2)
{return x1*y2-x2*y1;}
//计算a,b,c三点的叉积,判断a,b,c三点的位置关系
double cross(point a,point b,point c)
{return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);}
//计算两点间的最短距离
double dist(point a,point b)
{return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
//判断线段是否相交,相交为true,不相交为false
bool segcross(point a,point b,point c,point d)
{
int d1,d2,d3,d4;
d1=dblcmp(cross(a,b,c));
d2=dblcmp(cross(a,b,d));
d3=dblcmp(cross(c,d,a));
d4=dblcmp(cross(c,d,b));
if((d1^d2)==-2&&(d3^d4)==-2) return true;
return false;
}
int main()
{
double x,y1,y2,y3,y4;
int n;
while(~scanf("%d",&n))
{
int h=0,t=1;
s[0].x=0,s[0].y=5;
if(n==-1) break;
for(int i=0;i<n;i++)
{
cin>>x>>y1>>y2>>y3>>y4;
s[t].x=x,s[t++].y=y1;
s[t].x=x,s[t++].y=y2;
s[t].x=x,s[t++].y=y3;
s[t].x=x,s[t++].y=y4;
seg[h].a.x=x,seg[h].a.y=0;
seg[h].b.x=x,seg[h++].b.y=y1;
seg[h].a.x=x,seg[h].a.y=y2;
seg[h].b.x=x,seg[h++].b.y=y3;
seg[h].a.x=x,seg[h].a.y=y4;
seg[h].b.x=x,seg[h++].b.y=10;
}
s[t].x=10,s[t].y=5;
for(int i=0;i<=t;i++)
{
for(int j=0;j<=t;j++)
{
cost[i][j]=inf;
}
cost[i][i]=0;
}
for(int i=0;i<=t;i++)
{
for(int j=0;j<=t;j++)
{
if(i==j) continue;
Seg cnt;
int k;
cnt.a.x=s[i].x,cnt.a.y=s[i].y;
cnt.b.x=s[j].x,cnt.b.y=s[j].y;
for(k=0;k<h;k++)
{
if(segcross(cnt.a,cnt.b,seg[k].a,seg[k].b)) break;
}
if(k>=h) cost[i][j]=dist(cnt.a,cnt.b);
}
}
//floyd求最短路
for(int k=0;k<=t;k++)
{
for(int i=0;i<=t;i++)
{
for(int j=0;j<=t;j++)
{
if(cost[i][j]>cost[i][k]+cost[k][j])
cost[i][j]=cost[i][k]+cost[k][j];
}
}
}
printf("%.2lf\n",cost[0][t]);
}
return 0;
}