最短路径问题(信息学奥赛一本通 - T1342)

题目描述
平面上有 n 个点,每个点的坐标均在 -10000 ~ 10000 之间,其中的一些点之间有连线。

若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。

现在的任务是找出从一点到另一点之间的最短路径。

输入格式
第一行为整数 n。
第 2 行到第 n + 1 行,每行两个整数 x 和 y,描述了一个点的坐标。
第 n + 2 行为一个整数 m,表示图中连线的个数。
此后的 m 行,每行描述一条连线,由两个整数 i 和 j 组成,表示第 i 个点和第 j 个点之间有连线。
最后一行:两个整数 s 和 t,分别表示源点和目标点。

输出格式
一行,一个实数(保留两位小数),表示从 s 到 t 的最短路径长度。

输入样例
5
0 0
2 0
2 2
0 2
3 1
5
1 2
1 3
1 4
2 5
3 5
1 5

输出样例
3.41

数据范围
n ≤ 100


题解
Floyd:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

typedef pair<int, int> PII;

const int N = 110, INF = 0x7f7f7f7f;

PII g[N];
int n, m, s, e;
double d[N][N];

double get(int a, int b)
{
    
    
	int x = g[a].first - g[b].first;
	int y = g[a].second - g[b].second;
	return sqrt(x * x + y * y);
}

void floyd()
{
    
    
	for (int k = 1; k <= n; k ++)
		for (int i = 1; i <= n; i ++)
			for (int j = 1; j <= n; j ++)
				if(d[i][k] != INF && d[k][j] != INF)
					d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}

int main()
{
    
    
	cin >> n;	
	for (int i = 1; i <= n; i ++) cin >> g[i].first >> g[i].second;	
	cin >> m;
	
	memset(d, 0x7f, sizeof d);
	for (int i = 1; i <= n; i ++) d[i][i] = 0;
	
	while(m --)
	{
    
    
		int a, b;
		cin >> a >> b;
		d[a][b] = d[b][a] = min(d[a][b], get(a, b));
	}
	
	cin >> s >> e;
	
	floyd();
				
	printf("%.2f", d[s][e]);
	return 0;
}

ps:double 类型的数组不能用 0x3f 初始化,要用 0x7f

猜你喜欢

转载自blog.csdn.net/weixin_46239370/article/details/113822608