您的位置:首页 > 其它

zoj 1721 || poj 1556 The Doors

2011-04-03 18:32 302 查看
这题就考建图的。

从0,5到10,5,建图建好了,用最短路算法就很简单了。关键判断两个点是否可以相连,因为可能这俩点中间有墙,就不能连了。判断很好想,但是写着稍微麻烦点,不过数据挺小的。

代码注释的有,直接判断连线在x下的y坐标是否在墙上,如果在墙上,就不能连。

结构体里的p数组开小了 T T 。。。WA了许久,查到这个错误费了好长时间。。。 T T。。

zoj300了^ ^

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAX = 20;
const int MMAX = 80;
typedef struct WALL{
	double x;
	double p[5];
}WALL;
WALL wall[MAX];
double map[MMAX][MMAX];
int n,m;
double Distance(double x1,double y1,double x2,double y2)
{
	return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
}
double yyy(double x1,double y1,double x2,double y2,double x)
{
	return ( (y2-y1)/(x2-x1)*x + (x2*y1 - x1*y2)/(x2-x1) );
}
bool Con(double x1,double y1,double x2,double y2,int i,int k)
{
	int tmp;
	if( k < i )
		return true;
	for(int j=i; j<=k; j++)
	{
		double y = yyy(x1,y1,x2,y2,wall[j].x);
		if( y >= wall[j].p[1] && y <= wall[j].p[2] || y >= wall[j].p[3] && y <= wall[j].p[4] )
			continue;
		else
			return false;
	}
	return true;
}
void Buildmap()
{
	double bx = 0.0,by = 5.0;
	double ex = 10.0,ey = 5.0;
	if( Con(bx,by,ex,ey,1,m) )
	{
		double len = Distance(bx,by,ex,ey);
		map[0][m*4+1] = len;
	}
	
	for(int i=1; i<=m; i++)  // 起点建图  
		for(int k=1; k<=4; k++)
			if( Con(bx,by,wall[i].x,wall[i].p[k],1,i-1) )
			{
				double len = Distance(bx,by,wall[i].x,wall[i].p[k]);
				map[0][(i-1)*4+k] = len;
			}
			
	for(int i=1; i<=m; i++) // 终点建图 
		for(int k=1; k<=4; k++)
			if( Con(wall[i].x,wall[i].p[k],ex,ey,i+1,m) )
			{
				double len = Distance(ex,ey,wall[i].x,wall[i].p[k]);
				map[(i-1)*4+k][m*4+1] = len;
			}
	for(int i=1; i<m; i++) // 中间点建图 
		for(int p=1; p<=4; p++)
			for(int k=i+1; k<=m; k++)
				for(int q=1; q<=4; q++)
					if( Con( wall[i].x,wall[i].p[p],wall[k].x,wall[k].p[q],i+1,k-1) )
					{
						double len = Distance(wall[i].x,wall[i].p[p],wall[k].x,wall[k].p[q]);
						map[(i-1)*4+p][(k-1)*4+q] = len;
					}
}
const double inf = 10000000.0;
double Dijkstra(int s,int t,int n)
{
	double dis[MMAX];
	fill(dis,dis+MMAX,inf);
	bool used[MMAX];
	memset(used,false,sizeof(used));
	dis[s] = 0.0; used[s] = true;
	int now = s;
	for(int i=0; i<n; i++)
	{
		for(int k=0; k<=n; k++)
			if( map[now][k] >= 0.0 && dis[k] > dis[now] + map[now][k] )
				dis[k] = dis[now] + map[now][k];
		double min = inf;
		for(int k=0; k<=n; k++)
			if( !used[k] && dis[k] < min )
				min = dis[now = k];
		used[now] = 1;
	}
	return dis[t];
}
int main()
{
	while( ~scanf("%d",&m) && m != -1 )
	{
		for(int i=0; i<MMAX; i++)
			for(int k=0; k<MMAX; k++)
				map[i][k] = -1.0;
		for(int i=1; i<=m; i++)
		{
			scanf("%lf",&wall[i].x);
			for(int k=1; k<=4; k++)
				scanf("%lf",&wall[i].p[k]);
		}
		Buildmap();
		double ans = Dijkstra(0,m*4+1,m*4+1);
		printf("%.2lf/n",ans);
	}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: