Dijkstra+计算几何 POJ 2502 Subway

题目传送门

题意:列车上行驶40, 其余走路速度10.问从家到学校的最短时间

分析:关键是建图:相邻站点的速度是40,否则都可以走路10的速度.读入数据也很变态.

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;

const int N = 2e2 + 5;
const int E = N * N;
const double INF = 1e30;
struct Point	{
	double x, y;
}p[N];
bool vis[N];
double d[N];
double w[N][N];
double sx, sy, ex, ey;
int tot;

void Dijkstra(int s)	{
	memset (vis, false, sizeof (vis));
	for (int i=1; i<=tot; ++i)	{
		d[i] = INF;
	}
	d[s] = 0;
	for (int i=1; i<=tot; ++i)	{
		double mn = INF;	int x = -1;
		for (int j=1; j<=tot; ++j)	{
			if (!vis[j] && mn > d[j])	mn = d[x=j];
		}
		if (x == -1)	break;
		vis[x] = true;
		for (int j=1; j<=tot; ++j)	{
			if (!vis[j] && d[j] > d[x] + w[x][j])	{
				d[j] = d[x] + w[x][j];
			}
		}
	}
}

double squ(double x)	{
	return x * x;
}

double get_cost(Point p1, Point p2, int v)	{
	double dis = sqrt (squ (p1.x - p2.x) + squ (p1.y - p2.y)) / 1000;
	return dis / v;
}

int main(void)	{
	while (scanf ("%lf%lf%lf%lf", &sx, &sy, &ex, &ey) == 4)	{
		for (int i=1; i<N; ++i)	{
			for (int j=1; j<N; ++j)	{
				w[i][j] = INF;
			}
		}
		tot = 1;
		double x, y, l = tot + 1;
		p[tot].x = sx;	p[tot].y = sy;
		while (scanf ("%lf%lf", &x, &y) == 2)	{
			if (x == -1 && y == -1)	{
				for (int i=l; i<tot; ++i)	{
					double tim = get_cost (p[i], p[i+1], 40);
					if (w[i][i+1] > tim)	{
						w[i][i+1] = w[i+1][i] =  tim;
					}
				}
				l = tot + 1;
				continue;
			}
			p[++tot].x = x;	p[tot].y = y;
		}
		p[++tot].x = ex;	p[tot].y = ey;
		for (int i=1; i<tot; ++i)	{
			for (int j=i+1; j<=tot; ++j)	{
				double tim = get_cost (p[i], p[j], 10);
				if (w[i][j] > tim)	{
					w[i][j] = w[j][i] = tim;
				}
			}
		}
		Dijkstra (1);
		printf ("%.0f
", d[tot] * 60);
	}

	return 0;
}

  

编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/5008465.html