莱芜十七中网站,水利建设与管理司网站,建筑设计门户网站,企业域名申请流程1125. 牛的旅行 - AcWing题库
农民John的农场里有很多牧区#xff0c;有的路径连接一些特定的牧区。
一片所有连通的牧区称为一个牧场。
但是就目前而言#xff0c;你能看到至少有两个牧区不连通。
现在#xff0c;John想在农场里添加一条路径#xff08;注意#xff…1125. 牛的旅行 - AcWing题库
农民John的农场里有很多牧区有的路径连接一些特定的牧区。
一片所有连通的牧区称为一个牧场。
但是就目前而言你能看到至少有两个牧区不连通。
现在John想在农场里添加一条路径注意恰好一条。
一个牧场的直径就是牧场中最远的两个牧区的距离本题中所提到的所有距离指的都是最短的距离。
考虑如下的两个牧场每一个牧区都有自己的坐标 图 1 是有 5 个牧区的牧场牧区用“*”表示路径用直线表示。
图 1 所示的牧场的直径大约是 12.07106, 最远的两个牧区是 A 和 E它们之间的最短路径是 A-B-E。
图 2 是另一个牧场。
这两个牧场都在John的农场上。
John将会在两个牧场中各选一个牧区然后用一条路径连起来使得连通后这个新的更大的牧场有最小的直径。
注意如果两条路径中途相交我们不认为它们是连通的。
只有两条路径在同一个牧区相交我们才认为它们是连通的。
现在请你编程找出一条连接两个不同牧场的路径使得连上这条路径后所有牧场生成的新牧场和原有牧场中直径最大的牧场的直径尽可能小。
输出这个直径最小可能值。
输入格式
第 1 行一个整数 N, 表示牧区数
第 2 到 N1 行每行两个整数 X,Y 表示 N 个牧区的坐标。每个牧区的坐标都是不一样的。
第 N2 行到第 2*N1 行每行包括 N 个数字 ( 0或1 ) 表示一个对称邻接矩阵。
例如题目描述中的两个牧场的矩阵描述如下 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输入数据中至少包括两个不连通的牧区。
输出格式
只有一行包括一个实数表示所求答案。
数字保留六位小数。
数据范围
1≤N≤150 0≤X,Y≤105
输入样例
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输出样例
22.071068 解析
1.答案大于等于所有连通块直径的最大值
2.经过新边的最长的最短路径
具体过程
1.用floyd算法求出任意两点之间的最短距离
2.求出max[i]表示和i连通的且距离i最远的点的距离
3.情况1所有max[i]的最大值
情况2枚举在哪两个点之间连边。ij需要满足d[i,j]INF, maxd[i]dist[i,j]maxd[j]
#includeiostream
#includestring
#includecstring
#includecmath
#includectime
#includealgorithm
#includeutility
#includestack
#includequeue
#includevector
#includeset
#includemath.h
#includemap
#includesstream
#includedeque
#includeunordered_map
using namespace std;
const int N 150 5;
const double INF 1e20;
int n;
char g[N][N];
double d[N][N],maxd[N];
typedef pairdouble, double PII;
PII p[N];double get_dist(PII a, PII b) {double dx a.first - b.first;double dy a.second - b.second;return sqrt(dx * dx dy * dy);
}int main() {cin n;for (int i 1; i n; i) {scanf(%lf%lf, p[i].first, p[i].second);}for (int i 1; i n; i) {scanf(%s, g[i] 1);}for (int i 1; i n; i) {for (int j 1; j n; j) {if (g[i][j] 1)d[i][j] get_dist(p[i], p[j]);else if (i j)d[i][j] 0;else d[i][j] INF;}}for (int k 1; k n; k) {for (int i 1; i n; i) {for (int j 1; j n; j) {d[i][j] min(d[i][j], d[i][k] d[k][j]);}}}for (int i 1; i n; i) {for (int j 1; j n; j) {if (d[i][j] INF / 2)maxd[i] max(maxd[i], d[i][j]);}}double ret1 0;for (int i 1; i n; i) {ret1 max(ret1, maxd[i]);}double ret2 INF;for (int i 1; i n; i) {for (int j 1; j n; j) {if(d[i][j]INF/2)ret2 min(ret2, maxd[i] maxd[j] get_dist(p[i], p[j]));}}printf(%.6lf\n, max(ret1, ret2));return 0;
}