POJ 2502 Subway【spfa模板+建图】

POJ 2502 Subway

题目链接: vjudge传送门

题目大意:
给定学校和家的坐标,以及若干条地铁线途经的地铁站坐标,步行速度以及地铁速度,问从家到学校所花最少时间

具体思路:
最短路的模板题,难的是建图
要建立,家、学校以及每个地铁站之间的步行时间,同一线路相邻地铁站之间的行驶时间,并记录各点的标号

具体代码:

#include
#include
#include
#include
using namespace std;
typedef long long LL;
double const eps = 1e-5;
int const N = 205, M = 1e5 + 5;
int h[N];
double d[N];
int visit[N];
int cnt = 0;	//用于前向星建图
int n;	//总共有多少个地铁站,第0个是家,最后一个是学校
struct Node {
     
	int v;
	double w;
	int next;
}e[M];
struct Stop {
     
	int x, y;
}stop[N];
void add(int u, int v, double w)
{
     
	e[cnt].v = v;
	e[cnt].w = w;
	e[cnt].next = h[u];
	h[u] = cnt++;
}
double getLength(double x1, double y1, double x2, double y2, double spe)
{
     
	return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)) / spe / 1000 * 60;
}
void spfa()
{
     
	memset(visit, 0, sizeof(visit));
	for (int i = 1; i <= n; i++) d[i] = 1e18;	//初始化每个地方为无穷大
	d[0] = 0;
	queue<int> q;
	q.push(0);
	while (q.size())
	{
     
		int t = q.front();
		q.pop();
		visit[t] = 0;
		for (int i = h[t]; ~i; i = e[i].next)
		{
     
			int v = e[i].v;
			double w = d[t] + e[i].w;
			if (d[v] - w > eps) {
     
				d[v] = w;
				if (!visit[v]) {
     
					q.push(v);
					visit[v] = 1;
				}
			}
		}
	}
}

int main()
{
     
	memset(h, -1, sizeof(h));
	int sx, sy, ex, ey;
	int x, y;
	scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
	stop[0].x = sx, stop[0].y = sy;	//家,编号为0
	int num = 1;
	while (~scanf("%d%d", &x, &y))	//每条线路第一个站点
	{
     
		int xx, yy;
		stop[num].x = x, stop[num].y = y;
		while (~scanf("%d%d", &xx, &yy))
		{
     
			if (xx == -1 && yy== -1)break;	//线路结束
			stop[num+1].x = xx, stop[num+1].y = yy;
			double dis = getLength(x, y, xx, yy, 40);
			add(num, num + 1, dis);	//同一条线路,相邻的站点建图
			add(num + 1, num, dis);
			x = xx, y = yy;
			num++;
		}
		num++;
	}
	stop[num].x = ex, stop[num].y = ey;	//学校
	//求家、学校以及各个地铁站点之间的步行路线距离
	for(int i=0;i<= num;i++)
		for (int j = 0; j <= num; j++)
		{
     
			if (i == j)continue;
			double dis = getLength(stop[i].x, stop[i].y, stop[j].x, stop[j].y,10);
			add(i, j, dis);
		}
	n = num;	//记录总共多少个点(包括家和学校)
	spfa();
	printf("%d\n", int(d[num] + 0.5));	//四舍五入取整
	return 0;
}

你可能感兴趣的:(最短路,OJ题解)