main
黄海 2 years ago
parent e74778b9dd
commit c571254813

@ -146,7 +146,7 @@ const int INF = 0x3f3f3f3f;
PII q[N]; // 每个点的坐标 PII q[N]; // 每个点的坐标
char g[N][N]; // 邻接矩阵,记录是否中间有边 char g[N][N]; // 邻接矩阵,记录是否中间有边
double dist[N][N]; // 每两个牧区之间的距离 double dis[N][N]; // 每两个牧区之间的距离
double maxd[N]; // 距离牧区i最远的最短距离是多少 double maxd[N]; // 距离牧区i最远的最短距离是多少
// 欧几里得距离 // 欧几里得距离
@ -169,20 +169,19 @@ int main() {
// ① 距离只在同一连通块中存在不同的连通块间的距离是INF // ① 距离只在同一连通块中存在不同的连通块间的距离是INF
// ② 自己与自己的距离是0 // ② 自己与自己的距离是0
// ③ 两个牧区相连,距离=sqrt((x1-x2)^2+(y1-y2)^2) // ③ 两个牧区相连,距离=sqrt((x1-x2)^2+(y1-y2)^2)
// 本质: g + q => dist // 本质: g + q => dis
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) { for (int j = 0; j < n; j++) {
// 1. double数组在全局变量区默认值是0 // 1. double数组在全局变量区默认值是0
// 2. 当i==j时自己到自己的距离是0所以没动作直接使用默认值即d[i][i]=0,自己到自己没有距离 // 2. 当i==j时自己到自己的距离是0所以没动作直接使用默认值即d[i][i]=0,自己到自己没有距离
// 3. 当g[i][j]=='1'时,说明两者之间存在一条边,距离就是欧几里得距离计算办法 // 3. 当g[i][j]=='1'时,说明两者之间存在一条边,距离就是欧几里得距离计算办法
// 4. 否则就是没有路径 // 4. 否则就是没有路径
if (i == j) if (i == j)
dist[i][j] = 0; dis[i][j] = 0;
else if (g[i][j] == '1') else if (g[i][j] == '1')
dist[i][j] = get(q[i], q[j]); dis[i][j] = get(q[i], q[j]);
else // 注意由于dist数组是一个double类型不能用memset(0x3f)进行初始化正无穷 else // 注意由于dis数组是一个double类型不能用memset(0x3f)进行初始化正无穷
dist[i][j] = INF; dis[i][j] = INF;
}
} }
// ① Floyd算法 k,i,j // ① Floyd算法 k,i,j
@ -190,14 +189,15 @@ int main() {
for (int k = 0; k < n; k++) for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
// ② 未建设两个连通块之间线路前,每个点的最长 最短路径 // ② 未建设两个连通块之间线路前,每个点的最长 最短路径
// maxd[i]:由i出发可以走的最远距离
double res1 = 0; double res1 = 0;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) // ii() for (int j = 0; j < n; j++) // ii()
if (dist[i][j] < INF) maxd[i] = max(maxd[i], dist[i][j]); if (dis[i][j] < INF) maxd[i] = max(maxd[i], dis[i][j]);
// res1保持原来(两个牧场中)任意两个牧区间的最大距离(直径) // 所有点的最远距离PK,可以获取到最大直径
res1 = max(res1, maxd[i]); res1 = max(res1, maxd[i]);
} }
@ -205,7 +205,7 @@ int main() {
double res2 = INF; double res2 = INF;
for (int i = 0; i < n; i++) for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) for (int j = 0; j < n; j++)
if (dist[i][j] == INF) // 如果i,j不在同一个连通块内 if (dis[i][j] == INF) // 如果i,j不在同一个连通块内
// 连接原来不在同一连通块中的两个点后,可以取得的最小直径 // 连接原来不在同一连通块中的两个点后,可以取得的最小直径
res2 = min(res2, maxd[i] + maxd[j] + get(q[i], q[j])); res2 = min(res2, maxd[i] + maxd[j] + get(q[i], q[j]));
// PK一下 // PK一下

Loading…
Cancel
Save