此题仍是求单源最短路径问题,故想到dijkstra算法。此处的最短不是路径边权之和最短,而是路径最大边长最短,即求青蛙需要的最小步长。
改变dijstra算法的松弛条件:dis[i] = Math.min(dis[i], Math.max(dis[node], graph[node][i]));
源代码如下:
package onlineJudge;
import java.util.Scanner;
public class Poj2253_Dijkstra {
/**
* @param args
*/
static class Point{
int x, y;
}
static double[][] graph;
static int[] cer;
static double[] dis;
static int n;
static double twoPointDistance(Point a, Point b)
{
double distance, sqrtSum;
sqrtSum = Math.pow((a.x - b.x),2) + Math.pow((a.y - b.y), 2);
distance = Math.sqrt(sqrtSum);
return distance;
}
static int findLightestNode()
{
int node = 0;
double min = 999;
for(int i = 0; i < n; i++)
{
if(cer[i] == 0 && dis[i] < min)
{
node = i;
min = dis[i];
}
}
cer[node] = 1;
return node;
}
static void dijkstra()
{
for(int i = 0; i < n; i++)
{
dis[i] = 999;
cer[i] = 0;
}
dis[0] = 0;
cer[0] = 1;
int node = 0;
for(int i = 0; i < n-1; i++)
{
for(int j = 0; j < n; j++)
{
if(cer[j] == 0 && (Math.max(dis[node], graph[node][j]) < dis[j]))
dis[j] = Math.max(dis[node], graph[node][j]);
}
node = findLightestNode();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
n = scan.nextInt();
int iter = 1;
while(n != 0)
{
Point[] a = new Point[n];
graph = new double[n][n];
dis = new double[n];
cer = new int[n];
for(int i = 0; i < n; i++)
{
a[i] = new Point();
a[i].x = scan.nextInt();
a[i].y = scan.nextInt();
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
graph[i][j] = graph[j][i] = twoPointDistance(a[i], a[j]);
}
dijkstra();
System.out.println("Scenario #" + iter);
System.out.printf("Frog Distance = %.3f\n", dis[1]);
System.out.println();
iter++;
n = scan.nextInt();
}
scan.close();
}
}