HTML5-類庫系列 類名的各種操作
阿新 • • 發佈:2022-05-04
牛的旅行https://www.acwing.com/problem/content/1127/
求兩個連通塊連線後最大直徑 (可能是連線之前的直徑,可能是連線之後的最大值)
1.如果能到達 連線兩個點的距離 建圖
2.建圖後floyd
3.取dmin
#include <cstring> #include <iostream> #include <algorithm> #include <cmath> #define x first #define y second using namespace std; typedef pair<double, double> PDD; const int N = 155; const double INF = 1e20; int n; PDD q[N]; double d[N][N]; double maxd[N]; char g[N][N]; double get_dist(PDD a, PDD b) { double dx = a.x - b.x; double dy = a.y - b.y; return sqrt(dx * dx + dy * dy); } int main() { cin >> n; for (int i = 0; i < n; i ++ ) cin >> q[i].x >> q[i].y;//輸入點對的橫縱座標 for (int i = 0; i < n; i ++ ) cin >> g[i];//存領接矩陣 for (int i = 0; i < n; i ++ ) for (int j = 0; j < n; j ++ ) if (i == j) d[i][j] = 0;//到自己距離為0 else if (g[i][j] == '1') d[i][j] = get_dist(q[i], q[j]);//發現如果能“直接”走到的話,計算點的距離 else d[i][j] = INF;//如果不能走到 距離設定為正無窮 for (int k = 0; k < n; k ++ ) for (int i = 0; i < n; i ++ ) for (int j = 0; j < n; j ++ ) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);//做一遍的佛洛依德 計算“間接”兩點的最短路 double r1 = 0; for (int i = 0; i < n; i ++ ) { for (int j = 0; j < n; j ++ ) if (d[i][j] < INF / 2)//說明i走到的j maxd[i] = max(maxd[i], d[i][j]);//如果走不到 求maxd i存i能走到的點的最大值 r1 = max(r1, maxd[i]);//r1存某個連通塊的最大值 } double r2 = INF; for (int i = 0; i < n; i ++ ) for (int j = 0; j < n; j ++ ) if (d[i][j] > INF / 2)//如果不能走到 r2 = min(r2, maxd[i] + maxd[j] + get_dist(q[i], q[j]));//計算不能走到的最小值 也就是兩個連通塊的最小值 printf("%.6lf\n", max(r1, r2)); return 0; }