标签: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