热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Luogu1268树的重量

题中给出了邻接矩阵,而且n比较小,可以先考虑Floyd那样的做法一些三个点组成的点集他们之间的关系是满足dst[i][j]dst[i][k]dst[k]

题中给出了邻接矩阵,而且 n 比较小,可以先考虑 Floyd 那样的做法

一些三个点组成的点集他们之间的关系是满足 dst[i][j] = dst[i][k] + dst[k][j]
这些点的位置关系是可以先确定下来的

但是有些点之间的距离连出来会不一样,甚至还有些点加不到图中

考虑加入了图中但是距离不对的点,他们中间一定至少有个中转点
而在其他点的距离都计算正确的情况下,
枚举所有点作为中转点后取最小值
最小值一定是距离不正确的点对中的一个点(设为 k)向上连接的边长
用这个式子计算:val = (dst[i][j] + dst[j][k] + dst[k][i]) / 2 - dst[i][j]

简(hu)单(luan)证明一下就是如果最小值不是我们想要的东西的话
那一定是一个较大的值,而存在较小值一定是较大值是较大值多走了一条/些边
(自己画一条链计算端点的值随便找几个点试一下就发现了)

 感觉菊花图没法做,像是这样:

其实这种时候随意找两个点,他们之间的距离是正确的
再按照上面的计算方式是可以计算的

具体在实现的时候,发现他可以像 Floyd 差不多写

只要把他之前加入的都算上求最小值就行,
顺序讲道理是无所谓的只要把他和其他的都计算一遍就好

为了方便就从 1 到 n 依次加入了


 代码:

#include
#include
#include
#include
#include
#include
using namespace std;const int MAX_N = 35;int n, ans;
int dst[MAX_N][MAX_N];int main() {while (scanf("%d", &n) && n) {ans &#61; 0;for (int i &#61; 1; i <&#61; n; &#43;&#43;i) {for (int j &#61; i &#43; 1; j <&#61; n; &#43;&#43;j) {scanf("%d", &dst[i][j]);}}ans &#61; dst[1][2];for (int k &#61; 3; k <&#61; n; &#43;&#43;k) {register int cur_ans &#61; 0x3f3f3f3f;for (int i &#61; 1; i }


转:https://www.cnblogs.com/xcysblog/p/9880854.html



推荐阅读
author-avatar
吴佩珠淑杰
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有