// 6048K 547MS Java
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.Queue;
import java.util.ArrayList;
import java.util.LinkedList;
import java.math.*;
public class Main{
private static final long UNREACH = -1;
private static final int MAX = 210;
private static int sStoneNum;
private static double[] dis;
private static boolean[] djFlag;
public static double[][] stoneDistance;
public static Stone[] stones;
public class Stone {
public int x;
public int y;
}
public void reset() {
sStoneNum = 0;
for (int i = 0; i < MAX; i++) {
dis[i] = 0;
djFlag[i] = false;
for (int j = 0; j < MAX; j++) {
stoneDistance[i][j] = UNREACH;
}
}
}
public double dj(int stoneNum) {
for (int i = 0; i < stoneNum; i++) { // every node is connected, no need to check if connected
dis[i] = stoneDistance[0][i];
}
djFlag[0] = true; // begin stone join V1;
for (int j = 1; j < sStoneNum; j++) { // need sStoneNum-1 time caculate
int minId = -1;
int i = 0;
double minRange = 99999999;
for (; i < sStoneNum; i++) {
if (!djFlag[i]) {
if (minRange > dis[i]) {
minId = i;
minRange = dis[i];
}
}
}
djFlag[minId] = true; // minId node join V1
for (i = 0; i < sStoneNum; i++) { // update other nodes not in V1
if (!djFlag[i]) {
double maxRange = minRange > stoneDistance[minId][i] ? minRange : stoneDistance[minId][i];
dis[i] = dis[i] < maxRange ? dis[i] : maxRange;
}
}
}
return dis[1]; // floya is in 2th stone
}
public void solve(long caseId) {
System.out.println("Scenario #" + caseId);
// for (int i = 0; i < sStoneNum; i++) {
// System.out.println(stoneDistance[0][i]);
// }
String minRange = String.format("%.3f", dj(sStoneNum));
// double minRange = dj(sStoneNum);
System.out.println("Frog Distance = " + minRange + "\n");
reset();
}
public Main() {
stones = new Stone[MAX];
for (int i = 0; i < MAX; i++) {
stones[i] = new Stone();
}
dis = new double[MAX];
stoneDistance = new double[MAX][MAX];
djFlag = new boolean[MAX];
reset();
}
public static double getDistance(int x1, int x2, int y1, int y2) {
int xD = x1 - x2;
int yD = y1 - y2;
double orginalRes = Math.sqrt(xD*xD + yD*yD);
BigDecimal tmp = new BigDecimal(orginalRes);
return tmp.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static void main(String args[]) {
Main solver = new Main();
Scanner scanner = new Scanner(System.in);
int caseId = 1;
while(true) {
sStoneNum = scanner.nextInt();
if (sStoneNum == 0) {
return;
}
for (int i = 0; i < sStoneNum; i++) {
int x = scanner.nextInt();
int y = scanner.nextInt();
stones[i].x = x;
stones[i].y = y;
stoneDistance[i][i] = 0;
for (int j = 0; j < i; j++) {
double distance = getDistance(x, stones[j].x, y, stones[j].y);
// System.out.println(distance);
stoneDistance[i][j] = distance;
stoneDistance[j][i] = distance;
}
}
solver.solve(caseId++);
}
}
}
6048K 547MS Java
和1797一个模子,就是大小关系变了一下罢了,简直是做一送一,不过还是因为输出忘了加描述WA了一次 囧。
不同的是,这次的图是全直通图,因为题目没有规定青蛙最长能跳多远,所以默认青蛙可以从一个stone跳到任何其他的stone,
化成图就是图的每一个node都是互相直接连通的,因此在dj算法时,不用考虑两点之间是否直接连通。
麻烦一点的就是要先把每个stone之间的距离算出来,也简单,边接受输入边算就行了,注意保留3位四舍五入小数.
至于其他的步骤,和1797完全一样,
先解释一下题,青蛙在从起点跳到终点的path中,最长的一跳被成为 frogRange, 而因为从起点到终点会有多条不同的path,
那么要求就是这些path中最小的frogRange。
证明也一样:
假定现在从其实stoneB 到其他的没有确定到B的frogRange的其他stone, S1...SN, 而R1.....RN(目前从1...N点到B的最大frogRange)
满足R1<R2<...<RN, 那么从stone 1 到 B的最大frogRange必定是R1,
反证,如果存在其他的从stone1到B的path,那么该path必定会经过其他的stone, R2....RN, 而这些stone到B的frogRange都比R1大,
那么最终的frogRange也一定比R1大,因为按照题意,frograng是取path中最长的一跳.