题意:现在有n个点。会给你n个点的坐标。青蛙在1号点,他要去2号点。让你求出他去2号点所有通路中最长边中的最小值。
题解:最短路的一个变形。最短路让你求的是到达某点的最短路径。这道题求的是到达某点的最小边。
说一下这道题用dijkstra的思路。
我们都知道dijktra算法中,dis数组记录的是最短路的长度。这里把dist数组中存的东西改成到这点的最长边的最小边。
也就是把松弛操作中改成 dist【j】 = min(dist【j】,max(dist【MinNum】,map【MinNum】【j】));
这样证明:不断用用最小的未知边来和已确定边来比较,找出最长边中的最小边。如:你知道到达了I点的最大边的长度为len1,这时候你找到了到达j的最小边,看是否通过j点可以更新到达I的最长边的最小值。
详情看代码注释:
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include <iomanip>
using namespace std;
const int maxn = 210;
const int inf = 1e9;
double map[maxn][maxn]; // 地图
double dist[maxn]; // 储存到达i的最长边的最小值
bool vis[maxn]; // 标记数组。
int n;
struct P{
int x,y;
};
P point[maxn];
double dis(P a,P b){ //求距离
return sqrt((b.y - a.y)*(b.y - a.y) + (b.x - a.x)*(b.x - a.x));
}
void dijkstra(int start){
memset(vis,0,sizeof(vis));
for(int i = 1; i <= n; i ++)
dist[i] = inf; // 初始化 把所有点的最长边的最小值初始化成inf
dist[start] = 0;
for(int i = 1 ; i <= n ; i ++){
int MinNum,Min = inf;
for(int j = 1; j <= n ; j ++)
if(!vis[j] && dist[j] < Min){ // 找到‘未知’边中最小的
MinNum = j;
Min = dist[j];
}
vis[MinNum] = 1;
for(int j = 1; j <= n ; j ++) // 更新最长边中最小边。
dist[j] = min(dist[j],max(dist[MinNum],map[MinNum][j]));
}
}
int main(){
int c = 1;
while(cin >> n && n){
for(int i = 1;i <= n ; i ++) // 输入所有点
cin >> point[i].x >> point[i].y ;
for(int i = 1;i <= n ; i ++) // 建图
for(int j = i + 1 ; j <= n ; j ++ )
map[i][j] = map[j][i] = dis(point[i],point[j]);
dijkstra(1);
cout<<"Scenario #"<<c++<<endl;
printf("Frog Distance = %.3f\n",dist[2]); // 不知道为什么用lf就是wa。
cout<<endl;
}
return 0;
}