cowtours - codetrick
农民 John的农场里有很多牧区。有的路径连接一些特定的牧区。一片所有连通的牧区称为一个牧场。但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通。这样,Farmer John就有多个牧场了。
John想在农场里添加一条路径(注意,恰好一条)。对这条路径有以下限制:
一个牧场的直径就是牧场中最远的两个牧区的距离(本题中所提到的所有距离指的都是最短的距离)。考虑如下的有5个牧区的牧场,牧区用“*”表示,路径用直线表示。每一个牧区都有自己的坐标:
(15,15) (20,15)
D E
*-------*
| _/|
| _/ |
| _/ |
|/ |
*--------*-------*
A B C
(10,10) (15,10) (20,10)
这个牧场的直径大约是12.07106, 最远的两个牧区是A和E,它们之间的最短路径是A-B-E。
这里是另一个牧场:
*F(30,15)
/
_/
_/
/
*------*
G H
(25,10) (30,10)
这两个牧场都在John的农场上。John将会在两个牧场中各选一个牧区,然后用一条路径连起来,使得连通后这个新的更大的牧场有最小的直径。
注意,如果两条路径中途相交,我们不认为它们是连通的。只有两条路径在同一个牧区相交,我们才认为它们是连通的。
请编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。
http://sdjl.me/index.php/archives/107
http://blog.csdn.net/damonhao/article/details/19910787
http://jackneus.com/programming-archives/cow-tours/
http://www.iteye.com/topic/626000
Read full article from cowtours - codetrick
Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But,at the present time, you can find at least two pastures that cannot be connected by any sequence of cow paths, thus partitioning Farmer John's farm into multiple fields.
Farmer John would like add a single a cow path between one pair of pastures using the constraints below.
A field's `diameter' is defined to be the largest distance of all the shortest walks between any pair of pastures in the field. Consider the field below with five pastures, located at the points shown, and cow paths marked by lines:
15,15 20,15 D E *-------* | _/| | _/ | | _/ | |/ | *--------*-------* A B C 10,10 15,10 20,10
The `diameter' of this field is approximately 12.07106, since the longest of the set of shortest paths between pairs of pastures is the path from A to E (which includes the point set {A,B,E}). No other pair of pastures in this field is farther apart when connected by an optimal sequence of cow paths.
Suppose another field on the same plane is connected by cow paths as follows:
*F 30,15 / _/ _/ / *------ G H 25,10 30,10
In the scenario of just two fields on his farm, Farmer John would add a cow path between a point in each of these two fields (namely point sets {A,B,C,D,E} and {F,G,H}) so that the joined set of pastures {A,B,C,D,E,F,G,H} has the smallest possible diameter.
Note that cow paths do not connect just because they cross each other; they only connect at listed points.
The input contains the pastures, their locations, and a symmetric "adjacency" matrix that tells whether pastures are connected by cow paths. Pastures are not considered to be connected to themselves. Here's one annotated adjacency list for the pasture {A,B,C,D,E,F,G,H} as shown above:
A B C D E F G H A 0 1 0 0 0 0 0 0 B 1 0 1 1 1 0 0 0 C 0 1 0 0 1 0 0 0 D 0 1 0 0 1 0 0 0 E 0 1 1 1 0 0 0 0 F 0 0 0 0 0 0 1 0 G 0 0 0 0 0 1 0 1 H 0 0 0 0 0 0 1 0
Other equivalent adjacency lists might permute the rows and columns by using some order other than alphabetical to show the point connections. The input data contains no names for the points.
The input will contain at least two pastures that are not connected by any sequence of cow paths.
Find a way to connect exactly two pastures in the input with a cow path so that the new combined field has the smallest possible diameter of any possible pair of connected pastures. Output that smallest possible diameter.
PROGRAM NAME: cowtour
INPUT FORMAT
Line 1: | An integer, N (1 <= N <= 150), the number of pastures |
Line 2-N+1: | Two integers, X and Y (0 <= X ,Y<= 100000), that denote that X,Y grid location of the pastures; all input pastures are unique. |
Line N+2-2*N+1: | lines, each containing N digits (0 or 1) that represent the adjacency matrix as described above, where the rows' and columns' indices are in order of the points just listed. |
SAMPLE INPUT (file cowtour.in)
8 10 10 15 10 20 10 15 15 20 15 30 15 25 10 30 10 01000000 10111000 01001000 01001000 01110000 00000010 00000101 00000010
OUTPUT FORMAT
The output consists of a single line with the diameter of the newly joined pastures. Print the answer to exactly six decimal places. Do not perform any special rounding on your output.
SAMPLE OUTPUT (file cowtour.out)
22.071068http://www.iteye.com/topic/626000
农民 John的农场里有很多牧区。有的路径连接一些特定的牧区。一片所有连通的牧区称为一个牧场。但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通。这样,Farmer John就有多个牧场了。
John想在农场里添加一条路径(注意,恰好一条)。对这条路径有以下限制:
一个牧场的直径就是牧场中最远的两个牧区的距离(本题中所提到的所有距离指的都是最短的距离)。考虑如下的有5个牧区的牧场,牧区用“*”表示,路径用直线表示。每一个牧区都有自己的坐标:
(15,15) (20,15)
D E
*-------*
| _/|
| _/ |
| _/ |
|/ |
*--------*-------*
A B C
(10,10) (15,10) (20,10)
这个牧场的直径大约是12.07106, 最远的两个牧区是A和E,它们之间的最短路径是A-B-E。
这里是另一个牧场:
*F(30,15)
/
_/
_/
/
*------*
G H
(25,10) (30,10)
这两个牧场都在John的农场上。John将会在两个牧场中各选一个牧区,然后用一条路径连起来,使得连通后这个新的更大的牧场有最小的直径。
注意,如果两条路径中途相交,我们不认为它们是连通的。只有两条路径在同一个牧区相交,我们才认为它们是连通的。
请编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。
http://sdjl.me/index.php/archives/107
http://blog.csdn.net/damonhao/article/details/19910787
http://jackneus.com/programming-archives/cow-tours/
private static void run()
{
//计算每对pasture的最短路径
computeShortestPaths();
//计算每个pasture的半径,以及最大半径
computeRadius();
//计算最大直径
computeLongestDiameter();
answer = Math.max(longestDaimeter, longestRadius);
}
{
//计算每对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]);
}
}
{
//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]);
}
}
{
//计算每个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));
}
}
}
}
{
//计算最大直径
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));
}
}
}
}
http://www.iteye.com/topic/626000
Read full article from cowtours - codetrick