zoukankan      html  css  js  c++  java
  • LuoguP1268树的重量【构造/思维】By cellur925

    题目传送门

    Description

    给你一个矩阵$M$,$M(i,j)$表示$i$到$j$的最短距离。定义树的重量为树上各边权之和,对于任意给出的合法矩阵$M$,已知它所能表示树的重量是唯一确定的。给出一个矩阵,求它所表示的树的重量。


    Sol

    这道题我想了一会发现什么思路都没有...然后企图画一点图也无济于事...

    后来看题解发现我们其实可以从简单的角度入手,逐渐发现规律

    当有两个点的时候,显然答案就是$g(1,2)$。

    当有三个点的时候,如图,发生了分叉。(因为各点都是叶子节点)

    (图片引用自 @TsReaper

    设蓝线部分为$len$,那么树的重量就是$g(1,2)$+$len$。那么$len$部分怎么求?稍微想想可以得出$len=g(1,3)+g(2,3)-g(1,2)$再除以2。

    类比一下,当有四个...五个...六个...点的时候,也会在某一个路径上发生分叉,而一个点只可能从在它编号之前的点分叉而来。于是我们对于每个点,枚举一下它是从它之前哪个点分叉过来的,取个最小值累加即可得到答案。

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 
     7 int n,ans;
     8 int f[50][50];
     9 
    10 int main()
    11 {
    12     while(scanf("%d",&n)!=EOF&&n)
    13     {
    14         for(int i=1;i<=n-1;i++)
    15             for(int j=i+1;j<=n;j++)
    16                 scanf("%d",&f[i][j]),f[j][i]=f[i][j];
    17         ans+=f[1][2];
    18         for(int i=3;i<=n;i++)
    19         {
    20             int tmp=0x3f3f3f3f;
    21             for(int j=2;j<=i-1;j++)
    22                 tmp=min(tmp,(f[1][i]-f[1][j]+f[i][j])>>1);
    23             ans+=tmp;
    24         }
    25         printf("%d
    ",ans);
    26         ans=0;
    27         memset(f,0,sizeof(f));
    28     }
    29     return 0;
    30 }
    View Code
  • 相关阅读:
    操作系统_3:linux教程列表
    MongoEngine 查询语法
    Spark_1:教程索引
    软件需求十步走之阅读笔记03
    软件需求十步走之阅读笔记02
    软件需求十步走之阅读笔记01
    暑期学习四
    暑期学习三
    暑期学习二
    暑期学习一
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9781581.html
Copyright © 2011-2022 走看看