POJ 1556 The Doors (判断线段相交+dijkstra)

The Doors
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7392   Accepted: 2900

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length.
POJ 1556 The Doors (判断线段相交+dijkstra)_第1张图片

Input

The input data for the illustrated chamber would appear as follows.

2
4 2 7 8 9
7 3 4.5 6 7

The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.

Output

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.

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


题意:有n堵墙,每个墙上有两个门,给你墙的x坐标和门的Y坐标,求从(0,5)到(10,5)的最短距离

思路:看了之后秒想到最短路,刚开始没看到一个墙上只有两个门,想了很久,后来看到了就直接写了,在输入的时
候记录每条线段和每个点,并记录他们属于哪个墙,然后求出两个点两个点组成线段是否与其他的线段相交,如果不
相交,记录距离,最后dijkstra一下就行了。。。(PS:注意边界墙号的赋值,这点我坑了一个小时 = = 衰)

ac代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<queue>
#include<map> 
#include<vector>
#define MAXN 1000
#define LL long long
#define INF 0xfffffff*1.0
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
#include<iostream>
#include<algorithm>
using namespace std;
struct s
{
	double x,y;
	int num;
}list[MAXN];
struct ss
{
	double x1,x2,y1,y2;
	int k;
}line[MAXN];
double pri[MAXN][MAXN];
double D[MAXN];
int v[MAXN];
int cnt,cnt2;
double dis(s a,s b)
{
	return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
double fun(ss aa,double xx,double yy)
{
	return (aa.x2-aa.x1)*(yy-aa.y1)-(xx-aa.x1)*(aa.y2-aa.y1);
}
int check(ss A,ss B)
{
	if(max(A.x1,A.x2)<min(B.x1,B.x2))
	return 0;
	if(max(B.x1,B.x2)<min(A.x1,A.x2))
	return 0;
	if(max(A.y1,A.y2)<min(B.y1,B.y2))
	return 0;
	if(max(B.y1,B.y2)<min(A.y1,A.y2))
	return 0;
	if(fun(B,A.x1,A.y1)*fun(B,A.x2,A.y2)>1e-10)
	return 0;
	if(fun(A,B.x1,B.y1)*fun(A,B.x2,B.y2)>1e-10)
	return 0;
	return 1;
}
void dijkstra()
{
	double M;
	int k,i,j;
	mem(v);
	for(i=0;i<=cnt;i++)
	D[i]=pri[0][i];
	v[0]=1;
	for(i=0;i<cnt;i++)
	{
		M=INF;
		for(j=0;j<=cnt;j++)
		{
			if(!v[j]&&D[j]<M)
			{
				M=D[j];
				k=j;
			}
		}
		if(M==INF)
		break;
		v[k]=1;
		for(j=0;j<=cnt;j++)
		{
			if(D[j]>D[k]+pri[k][j])
			D[j]=D[k]+pri[k][j];
		}
	}
	printf("%.2lf\n",D[cnt]);
}
int main()
{
	int n,i,j,q;
	double p,y1,y2,y3,y4;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==-1)
		break;
		cnt=1;
		cnt2=0;
		list[0].x=0.0;list[0].y=5.0;list[0].num=0;//边界墙号赋值
		for(i=1;i<=n;i++)
		{
			scanf("%lf%lf%lf%lf%lf",&p,&y1,&y2,&y3,&y4);
			line[cnt2].x1=p;line[cnt2].y1=0;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=y1;
			line[cnt2].x1=p;line[cnt2].y1=y2;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=y3;
		    line[cnt2].x1=p;line[cnt2].y1=y4;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=10.0;
		    list[cnt].x=p;list[cnt].y=y1,list[cnt++].num=i;list[cnt].x=p;list[cnt].y=y2,list[cnt++].num=i;
		    list[cnt].x=p;list[cnt].y=y3,list[cnt++].num=i;list[cnt].x=p;list[cnt].y=y4,list[cnt++].num=i;
		}
		list[cnt].x=10.0;list[cnt].y=5.0;list[cnt].num=n+1;//边界墙号赋值
		for(i=0;i<=cnt;i++)
		for(j=i+1;j<=cnt;j++)
		pri[i][j]=pri[j][i]=INF;
		for(i=0;i<=cnt;i++)
		{
			ss a,b;
			a.x1=list[i].x;a.y1=list[i].y;
			for(j=i+1;j<=cnt;j++)
			{
				if(list[i].num==list[j].num)
				continue;
				a.x2=list[j].x;a.y2=list[j].y;
				int bz=0;
				for(q=0;q<cnt2;q++)
				{
					if(line[q].k==list[i].num||line[q].k==list[j].num)
					continue;
					if(check(a,line[q]))
					{
						bz=1;
						break;
					}
				}
				if(bz==0)
				pri[i][j]=pri[j][i]=dis(list[i],list[j]);
			}
		}
		dijkstra();
	}
	return 0;
}

 
 
 

你可能感兴趣的:(POJ 1556 The Doors (判断线段相交+dijkstra))