poj 2502 Subway md自闭了,之后再看吧f**k

本文详细探讨了Floyed与Dijkstra两种经典路径查找算法的实现方式,通过具体代码展示了两种算法如何应用于计算从家到学校的最短路径问题,比较了它们在处理带权图时的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Floyed

https://blog.youkuaiyun.com/u013480600/article/details/37875601

自己写的Floyed这个WA了,暂时还不知道为什么

//Floyed写法
#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int maxn = 210;
#define man_v (10000.0 / 60.0)
#define car_v (40000.0 / 60.0)

struct node
{
	double x, y;
};
node a[maxn];//用来保存数据

double Map[maxn][maxn];

double pow2(double x)
{
	return x * x;
}
double cal_time(int i, int j, double v)//坐标(i,j),速度为v
{
	//return sqrt(pow2(a[i].x - a[j].x) + pow2(a[i].y - a[j].y)) / v;

	return 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)) / v;

}

int main()
{
	for (int i = 0; i < maxn; i++)
		for (int j = 0; j < maxn; j++)
			Map[i][j] = i == j ? 0 : -1;

	cin >> a[0].x >> a[0].y >> a[1].x >> a[1].y;

	int cnt = 2;//a[maxn]已经保存了1和2,1 是起点家里,2是终点学校,所以从3开始记录

	//计算地铁的时间
	double pre_x = -1;//记录上一个坐标的x,防止计算时间的时候遇到已经到达终点的情况,那种情况直接不需要计算时间
	while (/*cin >> a[cnt].x >> a[cnt].y*/scanf("%lf%lf", &a[cnt].x, &a[cnt].y) == 2)
	{
		//每条地铁线路的终点后面是虚拟坐标对(-1,-1)
		if (pre_x != -1 && a[cnt].x != -1)//没有到达地铁终点,并且此次输入的也不是终点-1
		{
			//从上一站cnt-1站 到 这一站cnt站的时间,往返时间相同
			Map[cnt - 1][cnt] = Map[cnt][cnt - 1] = cal_time(cnt - 1, cnt, car_v);
		}
		pre_x = a[cnt].x;
		if (a[cnt].x != -1)
			cnt++;
	}

	//计算步行的时间
	for (int i = 0; i < cnt; i++)
		for (int j = i + 1; j < cnt; j++)
			//if (i != j)
			if (Map[i][j] == -1)
				Map[i][j] = Map[j][i] = cal_time(i, j, man_v);

	for (int k = 0; k < cnt; k++)
		for (int i = 0; i < cnt; i++)
			for (int j = 0; j < cnt; j++)
				if (Map[i][k] != -1 && Map[k][j] != -1)
					Map[i][j] = min(Map[i][j], Map[i][k] + Map[k][j]);
	cout << Map[0][1] << endl;//Map[1][2]表示从家到学校的最短距离/时间

	return 0;
}

Dijkstra

https://blog.youkuaiyun.com/llzhh/article/details/52421527

//Dijkstra写法
#pragma warning(disable:4996)
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 500;

double Map[maxn][maxn];
double dis[maxn];
int vis[maxn];
int n = 0;

double get_time(double x1, double y1, double x2, double y2)
{
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
void dijkstra(int s)
{
	for (int i = 0; i < n; i++)
		dis[i] = Map[i][s];
	vis[s] = 1;
	for (int i = 0; i < n; i++)
	{
		int Min = INF;
		int min_index = -1;
		for (int j = 0; j < n; j++)
		{
			if (Min > dis[j] && !vis[j])
			{
				min_index = j;
				Min = dis[j];
			}
		}

		if (min_index != -1)
			vis[min_index] = 1;
		for (int j = 0; j < n; j++)
		{
			if (dis[j] > dis[min_index] + Map[min_index][j] && !vis[j])
				dis[j] = dis[min_index] + Map[min_index][j];
		}
	}
}

struct node
{
	int x, y;
};
node a[maxn];

int main()
{
	cin >> a[0].x >> a[0].y >> a[1].x >> a[1].y;
	n = 2;

	int pre = 2;
	double x, y;

	while (scanf("%lf %lf", &x, &y) != EOF)
	{
		if (x == -1 && y == -1)
		{
			for (int i = pre; i < n - 1; i++)
			{
				double len = get_time(a[i].x, a[i].y, a[i + 1].x, a[i + 1].y) / 40000.0;
				Map[i][i + 1] = Map[i + 1][i] = len;
			}
			pre = n;
			continue;
		}
		a[n].x = x;
		a[n].y = y;
		n++;
	}

	for (int i = 0; i < n; i++)
	{
		for (int j = i + 1; j < n; j++)
		{
			if (Map[i][j] == 0)
			{
				double len = get_time(a[i].x, a[i].y, a[j].x, a[j].y) / 10000.0;
				Map[i][j] = Map[j][i] = len;
			}
		}
	}

	dijkstra(0);
	printf("%d", (int)(dis[1] * 60.0 + 0.5));

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值