1. 程式人生 > 其它 >HTML5-類庫系列 類名的各種操作

HTML5-類庫系列 類名的各種操作

牛的旅行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;
}