P1268 树的重量

    • 85通过
    • 141提交
  • 题目提供者该用户不存在
  • 标签树形结构
  • 难度提高+/省选-

提交该题 讨论 题解 记录

最新讨论

  • 有这种情况吗!!!!
  • 题意似乎有问题

题目描述

树可以用来表示物种之间的进化关系。一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异。现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树”。

令N={1..n},用一个N上的矩阵M来定义树T。其中,矩阵M满足:对于任意的i,j,k,有M[i,j]+M[j,k]<=M[i,k]。树T满足:

1.叶节点属于集合N;

2.边权均为非负整数;

3.dT(i,j)=M[i,j],其中dT(i,j)表示树上i到j的最短路径长度。

如下图,矩阵M描述了一棵树。

树的重量是指树上所有边权之和。对于任意给出的合法矩阵M,它所能表示树的重量是惟一确定的,不可能找到两棵不同重量的树,它们都符合矩阵M。你的任务就是,根据给出的矩阵M,计算M所表示树的重量。下图是上面给出的矩阵M所能表示的一棵树,这棵树的总重量为15。

输入输出格式

输入格式:

输入数据包含若干组数据。每组数据的第一行是一个整数n(2<n<30)。其后n-l行,给出的是矩阵M的一个上三角(不包含对角线),矩阵中所有元素是不超过100的非负整数。输入数据保证合法。

输入数据以n=0结尾。

输出格式:

对于每组输入,输出一行,一个整数,表示树的重量。

输入输出样例

输入样例#1:

5
5 9 12 8
8 11 7
5 1
4
4
15 36 60
31 55
36
0
输出样例#1:

15
71

分析:这种求一大堆数相加的题目显然不好直接下手,遇到这类问题先把数据化小,先假设n=1,直接输出0即可......如果n=2,两个点分别为a,b,那么答案就是a,b的距离,如果有3个点呢?假设这个点为c,因为所有的点都是叶子节点,那么c一定是在a,b的路径上的分叉的路径上:(画的丑轻喷......),设d(i,j)为i到j的距离,那么答案就是(d(a,c) + d(b,c) - d(a,b)) / 2 + d(a,b),如果多余3个节点呢?这个时候就必须要做一点特殊处理,把a当作一个“根”节点,因为所有的点都是连通的,那么j一定可以通过一条路径连接到a-i的路径上,那么再加一个点D,,可以发现答案其实就是3条线的和,但是我们只知道任意两个点之间的距离,怎么计算线呢?其实可以利用n=3的算法,答案为(d(a,c) + d(b,c) - d(a,b)) / 2 + d(a,b) + (d(a,d) + d(c,d) - d(a,c)) / 2这个时候要特别注意D是从哪条路径上分叉的,如果是从AB上分叉的可以发现会多算条路径(红色部分)怎么样才能不多算呢?其实可以发现,如果多加一个点,那么就要多计算一条路径,而这条路径就是最近的一条边分叉出来的,那么枚举边,计算最小值即可,同时要把A当作“根”节点,便于计算距离.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ,inf = 1e18; int n,d[maxn][maxn],ans,temp; int main()
{
while (scanf("%d", &n) && n)
{
for (int i = ; i <= n; i++)
for (int j = i + ; j <= n; j++)
{
scanf("%d", &d[i][j]);
d[j][i] = d[i][j];
}
ans = d[][];
for (int i = ; i <= n; i++)
{
temp = inf;
for (int j = ; j < i; j++)
temp = min(temp, (d[][i] + d[j][i] - d[][j]) / );
ans += temp;
}
printf("%d\n", ans);
} return ;
}

洛谷P1268 树的重量的更多相关文章

  1. 洛谷 P1268 树的重量 解题报告

    P1268 树的重量 题目描述 树可以用来表示物种之间的进化关系.一棵"进化树"是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题 ...

  2. 洛谷—— P1268 树的重量

    P1268 树的重量 构造类题目,看不出个所以然来... emmm,只好看题解: 只有两个点,那一条路径就是$ans$ 考虑三个点,那么$3$这个点相对于树上的路径(已经加入树上的边的距离) 为:$( ...

  3. 洛谷P1268 树的重量 【构造 + 枚举】

    题目描述 树可以用来表示物种之间的进化关系.一棵"进化树"是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离 ...

  4. 洛谷 P1268 树的重量 题解

    题面 目的:求出树的各边长度 条件:每个节点之间最短路.整个图中不存在负边 我们可以每一次把一个点加入树内,求出这个点和已经构建好的树的边的长度: 这个长度抽象理解一下就是(dis[i][j]+dis ...

  5. [Luogu P1268] 树的重量 (巧妙的构造题)

    题面 传送门:https://www.luogu.org/problemnew/show/P1268 Solution 这是一道极其巧妙的构造题 先做一个约定[i,j]表示从i到j的距离 我们可以先从 ...

  6. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  7. 洛谷P3384 树链剖分

    如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x ...

  8. P1268 树的重量

    题目描述 树可以用来表示物种之间的进化关系.一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树 ...

  9. P1268 树的重量【构造】

    题目描述 树可以用来表示物种之间的进化关系.一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树 ...

随机推荐

  1. Mysql中is marked as crashed and should be repaired问题的处理

    问题描述:浏览页面提示:.bbs[Table]threads' is marked as crashed and should be repaired 产生原因:表在查询或其它系统操作下损坏. 解决方 ...

  2. 【Linux】之shell特殊变量整理

    目录 1. 特殊变量列表 2. 特殊说明 在shell中变量名只能包含数字.字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量. 例如,$ 表示当前Shell进程的ID,即p ...

  3. ylbtech-dbs-m-QQ邮箱

    ylbtech-dbs:ylbtech-dbs-m-QQ邮箱 -- =============================================-- DatabaseName:QQ-Em ...

  4. jQuery实现的美观的倒计时实例代码

    <!DOCTYPE html><html><head><meta charset=" utf-8"><meta name=&q ...

  5. 30岁IT男连续工作一个月 突然失聪

    连续开发软件一个月,30 岁男子突然听不见声音了.近日,浙江省中山医院针灸科主任高宏主任中医师接诊了这名患者.高主任说,现在很多年轻人工作压力大,得突发性耳聋的越来越多,这种病听着不是威胁生命的大病, ...

  6. 和为S的两个数字VS和为s的连续正数序列

    题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. 例如输入数组1.2.4.7.11.15和数字15.由于4+11=15, ...

  7. 高级Java开发工程师

  8. list,set,map,数组之间的相互转换详细解析

    1.list转setSet set = new HashSet(new ArrayList()); 2.set转listList list = new ArrayList(new HashSet()) ...

  9. Singleton 单例模板

    // singleton.h #ifndef SINGLETON_H #define SINGLETON_H // 单例基类模板 template <class T> class Sing ...

  10. C++学习22 多态的概念及前提条件

    在<C++基类和派生类的赋值>一节中讲到,基类的指针也可以指向派生类对象.请看下面的例子: #include <iostream> using namespace std; c ...