讲的是,一只雄青蛙要从一个石头到另外一个石头上去找某只雌青蛙,但是这两个石头隔得太远,青蛙跳不过去,所幸,湖面上还有很多其他石头,所以青蛙可以借助别的石头一步一步地跳向那只雌青蛙所在的石头。显然青蛙可能有多种路径,比如其中一条是 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]); } }
POJ2253 Frogger 【Floyd】,布布扣,bubuko.com
时间: 2024-10-12 22:55:19