标签:each final from sample return 输出 tor int pac
POJ_1556_The Doors_判断线段相交+最短路
Description

Input
Output
Sample Input
1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1
Sample Output
10.00
10.06
你要通过一个包含阻碍墙的房间来找到最短路径的长度。
在x=0,x=10,y=0,y=10时,总会有边。路径的初始和终点总是(0,5)和(10,5),也会有从0到18的垂直墙,每一个都有两道门。
输出应该包含每个房间的一行输出。这一行应该包含小数点后两位小数的最小路径长度,并且总是显示小数点后两位小数。这条线不应该有空格。
把所有点拿出来连边建图,判断一下中间是否有挡住的墙壁即可。
这里的线段判断相交用的方法很菜:判断两直线交点在不在线段上。
因为有除法误差可能比较大。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <math.h>
using namespace std;
typedef double f2;
#define N 10050
#define eps 1e-6
int head[N],to[N],nxt[N],cnt,n,vis[N],tot,S,T,ghj;
f2 val[N],dis[N];
priority_queue<pair<f2,int> >q;
//********************************************
struct Point {
f2 x,y;
Point() {}
Point(f2 x_,f2 y_) :
x(x_),y(y_) {}
Point operator + (const Point &p) const {return Point(x+p.x,y+p.y);}
Point operator - (const Point &p) const {return Point(x-p.x,y-p.y);}
Point operator * (f2 rate) const {return Point(x*rate,y*rate);}
};
f2 dot(const Point &p1,const Point &p2) {return p1.x*p2.x+p1.y*p2.y;}
f2 cross(const Point &p1,const Point &p2) {return p1.x*p2.y-p1.y*p2.x;}
Point a[N];
typedef Point Vector;
struct Line {
Point p;Vector v;
Line() {}
Line(const Point &p_,const Vector &v_) :
p(p_),v(v_) {}
};
Line b[N];
Point get_point(const Line &l1,const Line &l2) {
Vector u=l1.p-l2.p;
f2 t=cross(l2.v,u)/cross(l1.v,l2.v);
return l1.p+l1.v*t;
}
bool judge(const Point &p1,const Point &p2,const Line &l) {
if(l.p.x<p1.x+eps||l.p.x>p2.x-eps) return 0;
Line l1=Line(p1,p2-p1),l2=Line(l.p,l.v-l.p);
Point p3=get_point(l1,l2);
return p3.x>p1.x&&p3.x<p2.x&&p3.y>l.p.y&&p3.y<l.v.y;
}
//********************************************************
inline void add(int u,int v,f2 w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
void dij() {
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[S]=0;q.push(make_pair(0,S));
while(!q.empty()) {
int x=q.top().second;q.pop();
if(vis[x]) continue;
vis[x]=1;
int i;
for(i=head[x];i;i=nxt[i]) {
if(dis[to[i]]>dis[x]+val[i]) {
dis[to[i]]=dis[x]+val[i];
q.push(make_pair(-dis[to[i]],to[i]));
}
}
}
printf("%.2lf\n",dis[T]);
}
void init() {
memset(head,0,sizeof(head)); cnt=0; tot=0; ghj=0;
}
int main() {
while(scanf("%d",&n)&&n!=-1) {
int i,j,k;
init();
f2 x,y,z,w,h;
for(i=1;i<=n;i++) {
scanf("%lf%lf%lf%lf%lf",&x,&y,&z,&w,&h);
a[++tot]=Point(x,y);
b[++ghj]=Line(Point(x,0),a[tot]);
a[++tot]=Point(x,z);
a[++tot]=Point(x,w);
b[++ghj]=Line(a[tot-1],a[tot]);
a[++tot]=Point(x,h);
b[++ghj]=Line(a[tot],Point(x,10));
}
a[++tot]=Point(0,5); S=tot;
a[++tot]=Point(10,5); T=tot;
for(i=1;i<=tot;i++) {
for(j=1;j<=tot;j++) {
if(a[j].x>a[i].x+eps) {
int flg=1;
for(k=1;k<=ghj;k++) {
if(judge(a[i],a[j],b[k])) {
flg=0; break;
}
}
if(flg) {
add(i,j,sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)));
//printf("%.2lf\n",sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)));
}
}
}
}
dij();
}
}
标签:each final from sample return 输出 tor int pac
原文地址:https://www.cnblogs.com/suika/p/9017755.html