首页 > 其他分享 >牛的旅行

牛的旅行

时间:2022-08-14 19:36:56浏览次数:86  
标签:旅行 连通 int MAX 路径 points dis

P1522 [USACO2.4] 牛的旅行 Cow Tours - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  • dfs为图中的连通块染色
  • floyd求出任意两点的最短距离,不连通就INF
  • 求出每个连通块中的每个点到达该连通块中其他点的所有最短路径(floyd求出)中的最大路径并记录,同时不断更新该连通块的直径,也就是所有最短路径中最大路径中最大的那个,作为该连通块的直径
  • 计算结果时遍历所有的点对i,j(不在同一个连通块内),答案可能会是三个中的一个
    • i这个连通块的直径
    • j这个连通块的直径
    • i到它自己那个连通块的最短路径最大值+j到它自己那个连通块的最短路径最大值+i,j两点之间的距离(桥的长度)
#include <bits/stdc++.h>
// https://www.luogu.com.cn/problem/P1522
using namespace std;
#define ll long long
#define MAX 155
#define INF 1e20
int n;
char t;
struct point
{
    int x, y;
} points[MAX];
double dis[MAX][MAX];
double distan(int x, int y)
{
    return sqrt(pow(points[x].x - points[y].x, 2) + pow(points[x].y - points[y].y, 2));
}
void init_dis()
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            dis[i][j] = INF;
}
void floyd()
{
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (dis[i][j] > dis[i][k] + dis[k][j])
                    dis[i][j] = dis[i][k] + dis[k][j];
}
void input()
{
    scanf("%d\n", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d%d", &points[i].x, &points[i].y);
    init_dis();
    for (int i = 1; i <= n; i++)
    {
        getchar();
        for (int j = 1; j <= n; j++)
        {
            t = getchar();
            if (t == '1')
                dis[i][j] = distan(i, j);
            else if (i == j)
                dis[i][j] = 0;
        }
    }
    floyd();
}
int colors[MAX];
void dfs(int now, int color)
{
    colors[now] = color;
    for (int i = 1; i <= n; i++)
        if (!colors[i] && dis[now][i] < INF)
            dfs(i, color);
}

void put_colors()
{
    int color = 0;
    for (int i = 1; i <= n; i++)
        if (!colors[i])
            dfs(i, ++color);
}
double max_pos[MAX] = {0.0}, diameter[MAX] = {0.0};
void find_min_max()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
            if (dis[i][j] < INF)
                max_pos[i] = max(max_pos[i], dis[i][j]);
        diameter[colors[i]] = max(diameter[colors[i]], max_pos[i]);
    }
}
double ans = INF;
void find_ans()
{
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++)
            if (colors[i] != colors[j])
                ans = min(ans, max(max(diameter[colors[i]], diameter[colors[j]]), (max_pos[i] + max_pos[j] + distan(i, j))));
    printf("%.6f\n", ans);
}
int main()
{
    input();
    put_colors();
    find_min_max();
    find_ans();
}

 

标签:旅行,连通,int,MAX,路径,points,dis
From: https://www.cnblogs.com/Wang-Xianyi/p/16586098.html

相关文章