1.Question:
题意:
题意:给出青蛙A,B和若干石头的坐标,现青蛙A想到青蛙B那,A可通过任意石头到达B,
问从A到B多条路径中的 最长边 中的 最短距离
2.Solution:
分析:这题是最短路的变形,以前求的是路径总长的最小值,而此题是通路中最长边的最小值,每条边的权值可以通过坐标算出,因为是单源起点,直接用SPFA算法或dijkstra算法就可以了
在这里,我对两种方法都进行了测试,发现时间效率是差不多的
但是我需要在这里解析一下题意:
在这道题中,我们单源最短路径中要维护的数据的性质发生了本质上的变化
1.在纯Shortest Path问题中,我们的要维护的数据时从源点到其他各点之间的最短的路径的总长度
2.在本题中,我们的题意是求在A,B两点中的所有的通路的最长边的最小值
所以说,我们这里的dis维护数组的实际上的内涵就是从源点到其他各点的通路中的最长的弧的最小值
在维护和松弛的过程中,我们的松弛策略也发生了变化,我们以前的最短路问题的松弛策略都是如果现在的新的通路dis权值小于之前的dis权值,我们松弛修改
但是在这里我们的松弛策略是,如果当前的通路的之前的dis和现在的选取的点的出边之间选取一个最大的,如果这个选出来的值比我们的dis要小,我们进行松弛
在SPFA中,我们是用边进行松弛,在队列顶点的的所有的出边和之前的顶点的dis中我们选取最大的一个
在Dijstra中,我们选择dis权值最小的一个然后用这个和所有的出边的最大值选取一个进行优化
3.Code:
Dijstra
/*
Problem: 2253 User: lantianheyeqi
Memory: 516K Time: 16MS
Language: C++ Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#include"cmath"
#define N 205
#define INF 0x7fffffff
using namespace std;
int n;
double dis[N];
double map[N][N];
bool book[N];
int dx[N];
int dy[N];
double cal(int i,int j)
{
double x=(dx[i]-dx[j])*(dx[i]-dx[j]);
double y=(dy[i]-dy[j])*(dy[i]-dy[j]);
return sqrt(0.0+x+y);
}
double dijstra()
{
memset(book,0,sizeof(book));
book[1]=1;
for(int i=1;i<=n;i++) dis[i]=map[1][i];
dis[1]=0;
for(int i=1;i<=n-1;i++)
{
double mink=INF;
int minpoint;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]<mink)
{
mink=dis[j];
minpoint=j;
}
}
book[minpoint]=1;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[j]>max(dis[minpoint],map[minpoint][j])) dis[j]=max(dis[minpoint],map[minpoint][j]);
}
}
return dis[2];
}
int main()
{
int t=1;
while(scanf("%d",&n)&&n!=0)
{
for(int i=1;i<=n;i++) scanf("%d%d",&dx[i],&dy[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=cal(i,j);
}
}
double k=dijstra();
printf("Scenario #%d\nFrog Distance = %.3lf\n\n",t++,k);
}
return 0;
}
SPFA
/*
Problem: 2253 User: lantianheyeqi
Memory: 676K Time: 16MS
Language: C++ Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#include"cmath"
#define N 205
#define INF 0x7fffffff
using namespace std;
double map[N][N];
int dx[N];
int dy[N];
int n;
double dis[N];
bool book[N];
double cal(int i,int j)
{
double x=(dx[i]-dx[j])*(dx[i]-dx[j]);
double y=(dy[i]-dy[j])*(dy[i]-dy[j]);
return sqrt(x+y+0.0);
}
double SPFA()
{
memset(book,0,sizeof(book));
memset(dis,0,sizeof(dis));
int queue[N*N];
int head=1;
int tail=2;
queue[1]=1;
book[1]=1;
for(int i=1;i<=n;i++) dis[i]=INF;
dis[1]=0;
while(head!=tail)
{
int point=queue[head];
for(int i=1;i<=n;i++)
{
if(dis[i]>max(dis[point],map[point][i]))
{
dis[i]=max(dis[point],map[point][i]);
if(book[i]==0)
{
book[i]=1;
queue[tail++]=i;
}
}
}
book[point]=0;
head++;
}
return dis[2];
}
int main()
{
int t=1;
while(scanf("%d",&n)&&n!=0)
{
for(int i=1;i<=n;i++) scanf("%d%d",&dx[i],&dy[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=cal(i,j);
}
}
double k=SPFA();
printf("Scenario #%d\nFrog Distance = %.3lf\n\n",t++,k);
}
return 0;
}