zoukankan      html  css  js  c++  java
  • #P1099 树网的核 题解

    题目描述

    题解

    这一题,刚开始看题目感觉好像很难,题目又长……一看数据范围,呵呵。

    已经给出来这是个DAG,所以不用担心连通性的问题。那么怎么做呢?

    朴素的做法是把树的直径的两个端点都统计出来,然后暴力算那个什么偏心距,这里可以用floyd预处理,反正才n才300。还有一点,怎么算一个点到一条路径的距离呢,很简单,计算点到路径的距离,由于这是一张树网,且已经预处理点对之间的距离,从而点k到路径(i,j)的距离即为

    1 (dist[k][i]+dist[k][j]-dist[i][j])/2 //可以画图理解一下,注意是没有环的。
    View Code


    然后就开始敲了,但后来发现好像不用管直径,只用枚举一条路径就行了(满足最优的路径一定在树的直径上)
    时间复杂度嘛……O(n^3)
    参考代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int inf=1e9;
     4 const int N=305;
     5 int n,m,a[N][N],ans=inf,dis,u,v,c;
     6 int main()
     7 {
     8     scanf("%d %d",&n,&m);
     9     for(int i=1;i<=n;i++)
    10     {
    11         for(int j=1;j<=n;j++)
    12         {
    13             if(i-j)
    14                 a[i][j]=inf;
    15         }
    16     }
    17     for(int i=1;i<n;i++)
    18     {
    19         scanf("%d%d%d",&u,&v,&c);
    20         a[u][v]=a[v][u]=c;
    21     }
    22     for(int k=1;k<=n;k++)
    23     {
    24         for(int i=1;i<=n;i++)
    25         {
    26             for(int j=1;j<=n;j++)
    27                 a[i][j]=min(a[i][k]+a[k][j],a[i][j]);
    28         }
    29     }
    30     for(int i=1;i<=n;i++)
    31     {
    32         for(int j=i;j<=n;j++)
    33         {
    34             if(a[i][j]<=m)
    35             {
    36                 dis=0;
    37                 for(int k=1;k<=n;k++)
    38                 {
    39                     dis=max(dis,(a[k][i]+a[k][j]-a[i][j])/2);
    40                 }
    41                 ans=min(dis,ans);
    42             }                
    43         }
    44     }
    45     printf("%d",ans);
    46     return 0;
    47 }
    View Code
  • 相关阅读:
    2020.11.6
    2020.7.15小日记
    P1536 村村通
    P1510 精卫填海
    P1020 导弹拦截
    P1164 小A点菜
    5.17练习总结
    P1135 奇怪的电梯
    P1101 单词方阵
    P1443 马的遍历
  • 原文地址:https://www.cnblogs.com/ssf-lrk/p/11194958.html
Copyright © 2011-2022 走看看