题面

传送门:https://www.luogu.org/problemnew/show/P1268


Solution

这是一道极其巧妙的构造题

先做一个约定[i,j]表示从i到j的距离

我们可以先从n=2,也就是最简单的情况来切入这道题

对于n=2,答案显然是[1,2]

接下来考虑n=3

如下图所示

这棵树一定是长成这样的

也就是说三这个节点一定是插在1与2两个节点之间的

我们可以发现,3节点的插入使得树的权值增加了([1,3]+[2,3]-[1,2])/2 (即紫线与蓝线的权值和减去绿线除以二)

我们可以把这个权值贡献的式子推广到一般情况

即x节点插入在[i,j]路径上

其对答案的贡献为([i,x]+[j,x]-[i,j])/2

接下来,我们继续把之前的结论推广到一般情况

四号节点接下来是不是有可能加入在[1,2],[1,3],[2,3]这三条路径中

答案要求整棵树权值和尽可能小,我们只需要在三种情况中选最小值就好

我想你已经找到了一个O(n^3)的算法

就是枚举3~n的插入点,再用两层循环枚举所插入的边

复杂度O(n^3)

事实上,我们已经可以过这道题了.

但我们的复杂度还可以更优

重新再看一下这张图

是不是可以发现我们紫色的那个其实是重复枚举

因为[1,4]+[3,4]-[1,3] 和[2,4]+[3,4]-[2,3] 其实都是一毛一样的!!!

这个结论也可以推广至一般状况中

所以说我们完全可以省去枚举中的一维

只枚举1~n就好

时间复杂度O(n^2)


Code

//Luogu P1268 树的重量
//May,30th,2018
//构造妙题
#include<iostream>
#include<cstdio>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=30+5;
int n,a[N][N];
int main()
{
while(1)
{
memset(a,0,sizeof a);
int ans=0;
n=read();
if(n==0) break;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
a[i][j]=a[j][i]=read(); ans+=a[1][2];
for(int i=3;i<=n;i++)
{
int t_ans=0x3f3f3f3f;
for(int j=1;j<i;j++)
for(int k=1;k<j;k++)
t_ans=min(t_ans,(a[j][i]+a[k][i]-a[j][k])/2);
ans+=t_ans;
}
printf("%d\n",ans);
}
return 0;
}

正解(三方)(C++)

//Luogu P1268 树的重量
//May,30th,2018
//构造妙题
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long read()
{
long long x=0,f=1; char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int N=30+5;
int n,a[N][N];
int main()
{
while(1)
{
memset(a,0,sizeof a);
int ans=0;
n=read();
if(n==0) break;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
a[i][j]=a[j][i]=read(); ans+=a[1][2];
for(int i=3;i<=n;i++)
{
int t_ans=0x3f3f3f3f;
for(int j=1;j<i;j++)
t_ans=min(t_ans,(a[j][i]+a[1][i]-a[j][1])/2);
ans+=t_ans;
}
printf("%d\n",ans);
}
return 0;
}

正解(平方)(C++)

[Luogu P1268] 树的重量 (巧妙的构造题)的更多相关文章

  1. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

  2. 【luogu P1268 树的重量】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1268 给定所有点间的最短路求原图所有路径和 形如: 我们需要计算红边+绿边 绿边 = (红边+蓝边+紫边)/ ...

  3. luogu P1268 树的重量

    一开始把这题想复杂了,,, 这里记\(di[i][j]\)表示\(i\)到\(j\)的距离 首先如果\(n=2\),答案显然为\(di[1][2]\) 如果\(n=3\) 懒得画图了盗图过来 那么3号 ...

  4. 洛谷—— P1268 树的重量

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

  5. 洛谷P1268 树的重量

    P1268 树的重量 85通过 141提交 题目提供者该用户不存在 标签树形结构 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 有这种情况吗!!!! 题意似乎有问题 题目描述 树可以用来表 ...

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

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

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

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

  8. P1268 树的重量【构造】

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

  9. P1268 树的重量

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

随机推荐

  1. Django-发送注册、忘记密码邮件验证-send_mail

    用户邮箱注册.发送验证码流程图 那,如何解决? 1.  setting配置邮箱参数 # 邮箱设置,需要在邮箱中开启smtp服务 # 提供服务的主机域名 EMAIL_HOST = 'smtp.163.c ...

  2. HTML+CSS系列:登录界面实现

    一.效果 二.具体实现 1.index.html <!DOCTYPE html> <html> <head> <meta charset="utf- ...

  3. vs调试程序缺少 msvcp140d.dll 解决方法

    简介一下吧: 如果只是为了解决问题请直接看第      7       点 ,谢谢. vs2013运行刚安装的opencv问题总结,尤其是电脑还很渣的情况下------花了我起码2天样子----很无奈 ...

  4. mac操作liunx

    mkdir demo //创建一个文件夹 touch index.html // 创建一个html文件 rm rouch index.html //删除找个index.html文件 rmdir dem ...

  5. intelliJ 软件项目打开运行

    1.导入项目 2.首先更改数据库,找到application-dev.yml文件,更改数据源 3.配置tomcat端口  找到application.yml 文件 然后打开pom.xml 更改版本号 ...

  6. 技术心得丨一种有效攻击BERT等模型的方法

    Is BERT Really Robust? A Strong Baseline for Natural Language Attack on Text Classification and Enta ...

  7. Git之多人协同开发

    一.获取远程库信息 1 2 3 $ git remote -v origin  https://github.com/xxxxx/node.git (fetch) origin  https://gi ...

  8. docker启动服务---------------nginx+php

    环境 首先安装Docker,无论你是Windows还是Linux.MocOS都可以.安装Docker自行百度. Docker镜像源 访问https://hub.docker.com即可,它是镜像大仓库 ...

  9. lumen容器模仿

    <?php class Container { private $bindings = []; private $instances = []; public function getClosu ...

  10. 第三十六章 Linux常用性能检测的指令

    作为一个Linux运维人员,介绍下常用的性能检测指令! 一.uptime 命令返回的信息: 19:08:17              //系统当前时间 up 127 days,  3:00     ...