POJ2253 青蛙跳 :http://poj.org/problem?id=2253
n为200。
题意为: 给出n个石头, 每个石头给出他们的X和Y坐标。
一只青蛙在这些石头上面跳来跳去。但是青蛙跳跃能力有限。
需要求的是,青蛙从石头1跳到石头2上,对他的跳跃能力要求最低为多少。
也就是石头1到石头2路径上,的最大边,最小可以为多少。
这里dis数组保存的就不是原点到各点的最短路,而是对青蛙而言,到达这个点所需要的最低跳跃距离。
每次跳跃过程中 ,更新、松弛 点的时候, 在 起点和 边权 之间选择较大的,然后更新值的时候 选取较小的。
结尾要多换一行!!!
说起来麻烦一点,看代码吧。
核心代码就一句。
基础最短路一里面用了已经会的Dijkstra,这次使用Spfa,没什么差别的。核心就在松弛那句话。
Spfa:
#include"cstdio"
#include"iostream"
#include"cstring"
#include"algorithm"
#include"vector"
#include"cmath"
#include"queue"
using namespace std;
#define INF 99999999
#define inf 1009
#define loop(x,y,z) for(x=y;x<z;x++)
#define ll long long
int n,m;
int book[inf],s,g;
double dis[inf];
int e[inf][inf];
queue<int>q;
struct node
{
int to;
double w;
node(int i,double j)
{
to=i;
w=j;
}
};
vector<node>edge[inf];
double cal(int i,int j)
{
double x=e[i][0]-e[j][0];
double y=e[i][1]-e[j][1];
return sqrt(x*x+y*y);
}
void init()
{
int i;
loop(i,0,n)
edge[i].clear();
memset(book,0,sizeof book);
loop(i,0,n)
dis[i]=INF;
dis[s]=0;
while(!q.empty())q.pop();
}
void Spfa()
{
int i;
q.push(s);
book[s]=1;
while(!q.empty())
{
int u=q.front();
q.pop();
book[u]=0;
int len=edge[u].size();
loop(i,0,len)
{
node& e=edge[u][i];
double gank=max(dis[u],e.w); //核心就是这个gank 此处取较大值
if(dis[e.to]>gank) //在松弛节点的时候 取较小值。本题的思路其实就是这两句话。
{
dis[e.to]=gank;
if(!book[e.to])
{
q.push(e.to);
book[e.to]=1;
}
}
}
}
}
int main()
{
int i,j,k=1;
s=0;
g=1;
while(~scanf("%d",&n)&&n)
{
init();
loop(i,0,n)
scanf("%d%d",&e[i][0],&e[i][1]);
loop(i,0,n)
loop(j,0,n)
edge[i].push_back(node(j,cal(i,j)));
Spfa();
printf("Scenario #%d\n",k++);
printf("Frog Distance = %.3f\n\n",dis[g]);
}
return 0;
}