首页 > 代码库 > POJ2253 Frogger 【Floyd】

POJ2253 Frogger 【Floyd】

讲的是,一只雄青蛙要从一个石头到另外一个石头上去找某只雌青蛙,但是这两个石头隔得太远,青蛙跳不过去,所幸,湖面上还有很多其他石头,所以青蛙可以借助别的石头一步一步地跳向那只雌青蛙所在的石头。显然青蛙可能有多种路径,比如其中一条是 2,3,4,2,1 ,它跳了五次,数字代表每次跳的距离也就是路径上相邻两个石头之间的距离,那么这只青蛙的弹跳能力至少是4才能跳过去。在其他的路径中,可能要求青蛙的弹跳是5,是8,是1,是100,等等,这个问题求青蛙需要的最小弹跳能力。其实也就是个最大值中取最小的问题。

直接求较为困难,我们试着用floyd算法来做这道题。Floyd算法非常好懂,两个结点,i,j,中间结点k枚举所有点,如果从i->k->j比较优,更新path[i][j]的值。

这里i->k->j比较优的情况就是i到j的距离比i到k和k到j都大,更新的值是i->k和k->j两者中的较大者(显然,要保证足够的弹跳能力)

path[i][j]的含义也就是i到j所需要的最小弹跳能力

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
struct point
{
	int x,y;
}p[222];
double path[222][222];
int main()
{
	#ifndef ONLINE_JUDGE
		freopen("G:/1.txt","r",stdin);
		freopen("G:/2.txt","w",stdout);
	#endif
	int casenum=0;
	while(true)
	{
		memset(p,0,sizeof(p));
		memset(path,0,sizeof(path));
		int stonenum;
		cin>>stonenum;
		if(!stonenum)
			break;
		casenum++;
		for(int i=1;i<=stonenum;i++)
			cin>>p[i].x>>p[i].y;
		for(int i=1;i<=stonenum-1;i++)
		{
			for(int j=i+1;j<=stonenum;j++)
			{
				path[j][i]=path[i][j]=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));
			}
		}
		for(int k=1;k<=stonenum;k++)
		{
			for(int i=1;i<=stonenum-1;i++)
			{
				for(int j=i+1;j<=stonenum;j++)
				{
					if(path[i][j]>path[i][k]&&path[i][j]>path[k][j])
					{
						path[i][j]=path[j][i]=max(path[i][k],path[k][j]);
					}
				}
			}
		}
		printf("Scenario #%d\n",casenum);
		printf("Frog Distance = %.3f\n\n",path[1][2]);
	}
}