POJ 2253

大概题意,给出N个点的坐标,A蛙在第一块石头上,B蛙在第二块石头上,A蛙要到B蛙所在的石头上去。其中,A蛙能从自己当前所在石头跳向另外的任意一块石头。选择一条路径,该路径上的每次从一块石头跳向另一块石头的距离的最大值在所有路径中是最小的, 求这个最小的最大跳的距离。(2<= N <= 200)

思路:刚刚看到这道题目的时候真的没什么思路,匆匆的写了一个 DFS+剪枝 果断超时,只是想试试那个剪枝的优化效果,看能不能卡一下,但是并不能。

然后再想想,只是题目中N小于200这个条件太显眼了,3方的时间复杂度肯定是没有问题的。

关键是怎么把问题转化为最短路问题,对于我们每条路径上的每一跳的最大距离,它应该是我们这条路径上的权值。

意思就是若 I 到 J 的权值是d1, 而 J 到 K 的权值是 d2,那么 I 到 K 的权值就可能是 max(d1, d2); 那么我们的思路就只是把 d1 + d2 转换成 max(d1, d2)而已;最主要是的还是思路的转换!

然后就基本上所学的最短路算法都能解决这个问题。

下面还是贴上我这丑陋的代码吧,用的是floyd算法。

#include 
#include  
#include 
#include 
#define pii pair
#define x first
#define y second
#define MAXN 201
using namespace std;
double dis(pii s, pii t) {
	double a = s.x - t.x, b = s.y - t.y;
	return sqrt(a * a + b * b);
}
int main() {
	int N, tt = 1;
	while (~scanf("%d", &N) && N) {
		pii s, t;
		cin >> s.x >> s.y >> t.x >> t.y;
		vector vec(N);
		for (int i = 1; i < N - 1; ++i) scanf("%d%d", &vec[i].x, &vec[i].y);
		vec[0] = s, vec[N - 1] = t;
		double d[MAXN][MAXN];
		for (int i = 0; i < N; ++i) {
			for (int j = i; j < N; ++j) {
				if (i == j) d[i][j] = 0;
				else d[i][j] = d[j][i] = dis(vec[i], vec[j]);
			}
		}
		for (int k = 0; k < N; ++k) {
			for (int i = 0; i < N; ++i) {
				for (int j = 0; j < N; ++j) {
					d[i][j] = min(d[i][j], max(d[i][k], d[k][j]));
				}
			}
		}
		cout << "Scenario #" << tt++ << endl << "Frog Distance = ";
		printf("%.3lf\n\n", d[0][N - 1]);
	}
	return 0;
}


你可能感兴趣的:(POJ 2253)