ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

牛的旅行

2022-08-14 19:31:31  阅读:155  来源: 互联网

标签:旅行 连通 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
来源: https://www.cnblogs.com/Wang-Xianyi/p/16586098.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有