这道题需要用到Floyd最短路径算法来求每对点之间的最短路径。
定义一个概念----半径。在求出每对点之间的最短路径后,用radius[i]来表示所有i可达的点j中,i到j的最短路径最大值。
当我们在A片区(一些互相可达的点组成一个片区)中的点a与B片区中的点b之间修一条路后,这个新片区的直径就是以下三个值的和:
1、a点的半径。
2、b点的半径。
3、这条新路的长度,即a与b在坐标系上的距离。
那么尝试在所有不可达的两个点之间修路就可以得到所有新片区的直径。
注意有一种情况,如在a、b中修路后,得到的新片区直径为d,但是它可能小于另一个片区C的半径,因此要在所有直径与半径中取出最大值才是题目所求。
定义一个概念----半径。在求出每对点之间的最短路径后,用radius[i]来表示所有i可达的点j中,i到j的最短路径最大值。
当我们在A片区(一些互相可达的点组成一个片区)中的点a与B片区中的点b之间修一条路后,这个新片区的直径就是以下三个值的和:
1、a点的半径。
2、b点的半径。
3、这条新路的长度,即a与b在坐标系上的距离。
那么尝试在所有不可达的两个点之间修路就可以得到所有新片区的直径。
注意有一种情况,如在a、b中修路后,得到的新片区直径为d,但是它可能小于另一个片区C的半径,因此要在所有直径与半径中取出最大值才是题目所求。
Code
/**//*
ID: sdjllyh1
PROG: cowtour
LANG: JAVA
complete date: 2008/12/24
complexity: O(n ^ 3)
author: LiuYongHui From GuiZhou University Of China
more article: www.cnblogs.com/sdjls
*/
import java.io.*;
import java.util.*;
import java.text.*;
public class cowtour
{
private static int n;
private static double[][] distance;//distance[i][j]表示第i个pasture与第j个pasture之间的最短路径,若i、j直接联通,distance[i][j]初始化为它们之间的路径长,否则初始化为一个较大值
private static double[] radius;//radius[i]表示在添加一条路径之前,第i个pasture与所有可达pasture之间的最大路径,这里的路径是到达另一个pasture的最短路径。
private static double[] pastureX, pastureY;//pasture们的坐标
private static double longestDaimeter;//最大直径
private static double longestRadius;//最大半径
private static double answer;//题目输出
public static void main(String[] args) throws IOException
{
init();
run();
output();
System.exit(0);
}
private static void run()
{
//计算每对pasture的最短路径
computeShortestPaths();
//计算每个pasture的半径,以及最大半径
computeRadius();
//计算最大直径
computeLongestDiameter();
answer = Math.max(longestDaimeter, longestRadius);
}
private static void computeShortestPaths()
{
//Floyd最短路算法求出每对pastures之间的最短路径
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
distance[i][j] = Math.min(distance[i][j], distance[i][k] + distance[k][j]);
}
}
private static void computeRadius()
{
//计算每个pasture的半径
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//如果i可达j
if (distance[i][j] != Double.MAX_VALUE)
{
//保存最大的最短路径作为半径
radius[i] = Math.max(radius[i], distance[i][j]);
}
}
}
//计算最大半径
for (int i = 0; i < n; i++)
{
longestRadius = Math.max(longestRadius, radius[i]);
}
}
private static void computeLongestDiameter()
{
//计算最大直径
longestDaimeter = Double.MAX_VALUE;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//如果i、j不可达
if (distance[i][j] == Double.MAX_VALUE)
{
//尝试联通i、j,并保存最大直径
longestDaimeter = Math.min(longestDaimeter, radius[i] + radius[j] + calcDistance(i, j));
}
}
}
}
//计算pasture1与pasture2在坐标系上的距离
private static double calcDistance(int pasture1, int pasture2)
{
return Math.sqrt((pastureX[pasture1] - pastureX[pasture2]) * (pastureX[pasture1] - pastureX[pasture2])
+ (pastureY[pasture1] - pastureY[pasture2]) * (pastureY[pasture1] - pastureY[pasture2]));
}
private static void init() throws IOException
{
BufferedReader f = new BufferedReader(new FileReader("cowtour.in"));
n = Integer.parseInt(f.readLine());
distance = new double[n][n];
radius = new double[n];
pastureX = new double[n];
pastureY = new double[n];
for (int i = 0; i < n; i++)
{
StringTokenizer st = new StringTokenizer(f.readLine());
pastureX[i] = Double.parseDouble(st.nextToken());
pastureY[i] = Double.parseDouble(st.nextToken());
}
for (int i = 0; i < n; i++)
{
String str = f.readLine();
for (int j = 0; j < n; j++)
{
if ((str.charAt(j) == '1') || (i == j))
{
distance[i][j] = calcDistance(i, j);
}
else
{
distance[i][j] = Double.MAX_VALUE;
}
}
}
f.close();
}
private static void output() throws IOException
{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("cowtour.out")));
DecimalFormat df = new DecimalFormat("0.000000");
out.println(df.format(answer));
out.close();
}
}
/**//*
ID: sdjllyh1
PROG: cowtour
LANG: JAVA
complete date: 2008/12/24
complexity: O(n ^ 3)
author: LiuYongHui From GuiZhou University Of China
more article: www.cnblogs.com/sdjls
*/
import java.io.*;
import java.util.*;
import java.text.*;
public class cowtour
{
private static int n;
private static double[][] distance;//distance[i][j]表示第i个pasture与第j个pasture之间的最短路径,若i、j直接联通,distance[i][j]初始化为它们之间的路径长,否则初始化为一个较大值
private static double[] radius;//radius[i]表示在添加一条路径之前,第i个pasture与所有可达pasture之间的最大路径,这里的路径是到达另一个pasture的最短路径。
private static double[] pastureX, pastureY;//pasture们的坐标
private static double longestDaimeter;//最大直径
private static double longestRadius;//最大半径
private static double answer;//题目输出
public static void main(String[] args) throws IOException
{
init();
run();
output();
System.exit(0);
}
private static void run()
{
//计算每对pasture的最短路径
computeShortestPaths();
//计算每个pasture的半径,以及最大半径
computeRadius();
//计算最大直径
computeLongestDiameter();
answer = Math.max(longestDaimeter, longestRadius);
}
private static void computeShortestPaths()
{
//Floyd最短路算法求出每对pastures之间的最短路径
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
distance[i][j] = Math.min(distance[i][j], distance[i][k] + distance[k][j]);
}
}
private static void computeRadius()
{
//计算每个pasture的半径
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//如果i可达j
if (distance[i][j] != Double.MAX_VALUE)
{
//保存最大的最短路径作为半径
radius[i] = Math.max(radius[i], distance[i][j]);
}
}
}
//计算最大半径
for (int i = 0; i < n; i++)
{
longestRadius = Math.max(longestRadius, radius[i]);
}
}
private static void computeLongestDiameter()
{
//计算最大直径
longestDaimeter = Double.MAX_VALUE;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
//如果i、j不可达
if (distance[i][j] == Double.MAX_VALUE)
{
//尝试联通i、j,并保存最大直径
longestDaimeter = Math.min(longestDaimeter, radius[i] + radius[j] + calcDistance(i, j));
}
}
}
}
//计算pasture1与pasture2在坐标系上的距离
private static double calcDistance(int pasture1, int pasture2)
{
return Math.sqrt((pastureX[pasture1] - pastureX[pasture2]) * (pastureX[pasture1] - pastureX[pasture2])
+ (pastureY[pasture1] - pastureY[pasture2]) * (pastureY[pasture1] - pastureY[pasture2]));
}
private static void init() throws IOException
{
BufferedReader f = new BufferedReader(new FileReader("cowtour.in"));
n = Integer.parseInt(f.readLine());
distance = new double[n][n];
radius = new double[n];
pastureX = new double[n];
pastureY = new double[n];
for (int i = 0; i < n; i++)
{
StringTokenizer st = new StringTokenizer(f.readLine());
pastureX[i] = Double.parseDouble(st.nextToken());
pastureY[i] = Double.parseDouble(st.nextToken());
}
for (int i = 0; i < n; i++)
{
String str = f.readLine();
for (int j = 0; j < n; j++)
{
if ((str.charAt(j) == '1') || (i == j))
{
distance[i][j] = calcDistance(i, j);
}
else
{
distance[i][j] = Double.MAX_VALUE;
}
}
}
f.close();
}
private static void output() throws IOException
{
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("cowtour.out")));
DecimalFormat df = new DecimalFormat("0.000000");
out.println(df.format(answer));
out.close();
}
}