惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - Franky
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
Jina AI
Jina AI
博客园 - 聂微东
S
SegmentFault 最新的问题
量子位
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园_首页

distjr_的博客

最新 | Galgame Maker 运行时引擎 README 最新 | 关于我的高中三年 | distjr_的博客 欸嘿 | distjr_的博客 最新 | 画中少女 | distjr_的博客 天津行记 | distjr_的博客 最终选择去天津大学了 | distjr_的博客 上伊那牡丹,看完了 | distjr_的博客 上伊那牡丹,看完了 | distjr_的博客 帖子测试 | distjr_的博客 最新 | 关于我的高中三年 | distjr_的博客 最新 | KeepOpen:一款保持移动硬盘开启状态的小工具 | distjr_的博客 最新 | KeepOpen:一款保持移动硬盘开启状态的小工具 | distjr_的博客 最新 | 关于我的高中三年 | distjr_的博客 一款基于Python的随机学生点名器 | distjr_的博客 最新 | 一款基于Python的随机学生点名器 | distjr_的博客 U571839 千本桜 题解 | distjr_的博客 巴别塔 | distjr_的博客 土地 | distjr_的博客 土地 | distjr_的博客 一九六八年 | distjr_的博客 一九六八年 | distjr_的博客 原野 | distjr_的博客 原野 | distjr_的博客 一种基于人工智能技术的系统发生树绘制与物种演化路径推断系统 | distjr_的博客 一种基于人工智能技术的系统发生树绘制与物种演化路径推断系统 | distjr_的博客 回来?Ⅱ | distjr_的博客 回来?Ⅱ | distjr_的博客 U314392 distjr_想买书 题解 | distjr_的博客 U314392 distjr_想买书 题解 | distjr_的博客 天涯边 | distjr_的博客
U571839 千本桜 题解 | distjr_的博客
文章作者: distjr_ · 2025-08-21 · via distjr_的博客

思路

本题是一个最小直径生成树(MDST)的模板题。

详细的思路等请参考OI-Wiki上的讲解。

std

/**
 * @file hatsune.cpp
 * @brief Solution of Luogu U571839
 * @date 2025-08-21
 */
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
#define ll long long
using namespace std;

constexpr int MAXN = 510;
ll d[MAXN][MAXN], rk[MAXN][MAXN], val[MAXN];
constexpr ll INF = 1e17;
int n, m;

bool cmp(int a, int b) { return val[a] < val[b]; }

void floyd()
{
    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}

struct node
{
    ll u, v, w;
} a[MAXN * (MAXN - 1) / 2];

int main()
{
    for (int i = 1; i <= 501; ++i)
        for (int j = 1; j <= 501; ++j)
            d[i][j] = INF;
    for (int i = 1; i <= 501; ++i)
        d[i][i] = 0;
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; ++i)
    {
        ll u, v, w;
        scanf("%lld %lld %lld", &u, &v, &w);
        w *= 2;
        d[u][v] = w, d[v][u] = w;
        a[i].u = u, a[i].v = v, a[i].w = w;
    }
    floyd();
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            rk[i][j] = j;
            val[j] = d[i][j];
        }
        sort(rk[i] + 1, rk[i] + 1 + n, cmp);
    }
    ll P = 0, ansP = INF;
    for (int i = 1; i <= n; i++)
    {
        if (d[i][rk[i][n]] * 2 < ansP)
        {
            ansP = d[i][rk[i][n]] * 2;
            P = i;
        }
    }
    int f1 = 0, f2 = 0;
    ll disu = INT_MIN, disv = INT_MIN, ansL = INF;
    for (int i = 1; i <= m; i++)
    {
        ll u = a[i].u, v = a[i].v, w = a[i].w;
        for (int p = n, i = n - 1; i >= 1; i--)
        {
            if (d[v][rk[u][i]] > d[v][rk[u][p]])
            {
                if (d[u][rk[u][i]] + d[v][rk[u][p]] + w < ansL)
                {
                    ansL = d[u][rk[u][i]] + d[v][rk[u][p]] + w;
                    f1 = u, f2 = v;
                    disu = (d[u][rk[u][i]] + d[v][rk[u][p]] + w) / 2 - d[u][rk[u][i]];
                    disv = w - disu;
                }
                p = i;
            }
        }
    }
    printf("%lld\n", min(ansP, ansL) / 2);
    return 0;
}