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. TortoiseSVN使用详细步骤

    1 安装及下载client 端 2 什么是SVN(Subversion)? 3 为甚么要用SVN? 4 怎么样在Windows下面建立SVN Repository? 5 建立一个Working目录 6 ...

  2. 7. redis优化

    一. redis使用上的优化 精简键名和键值 键名:尽量精简,但是也不能单纯为了节约空间而使用不易理解的键名. 键值:对于键值的数量固定的话可以使用0和1这样的数字来表示,(例如:male/femal ...

  3. java.lang.ClassNotFoundException: org.eclipse.jetty.plus.webapp.EnvConfiguration

    最近刚接触jetty,在myeclipse8.6中加入了一个项目,运行时就出了这个java.lang.ClassNotFoundException: org.eclipse.jetty.plus.we ...

  4. Java面试必备知识

    JAVA面试必备知识 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可 ...

  5. C# 通过委托控制进度条以及多线程更新控件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. xpath提取目录下所有标签内的内容,递归 //text()

    利用xpath来提取所有标签里面的内容,即使标签头不同 #-*-coding:utf8-*- import re import os from lxml import etree html = ''' ...

  7. linux命令(7)killall

    killall命令: Linux系统中的killall命令用于杀死指定名字的进程(kill processes by name).我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀 ...

  8. JAVA算数运算符

    算数运算符 序号 算数运算符 含义用法 特殊含义用法 1 + 加法 字符串连接 2 - 减法   3 * 乘法   4 / 除法   5 % 取余   实例: public class Test{ p ...

  9. C++学习33 函数模板

    在<C++函数重载>一节中,为了求三个数的最大值,我们通过函数重载定义了三个名字相同.参数列表不同的函数,如下所示: //求三个整数的最大值 int max(int a, int b, i ...

  10. Understanding Asynchronous IO With Python 3.4's Asyncio And Node.js

    [转自]http://sahandsaba.com/understanding-asyncio-node-js-python-3-4.html Introduction I spent this su ...