zoukankan      html  css  js  c++  java
  • 【noip2007】树网的核

    题解:

    首先我们要知道一个性质:如果有多条直径 这个核不论在哪条直径上 答案都是一样的

    这样我们就可以随便找一条直径 在这条直径上枚举核的位置

    并且dfs预处理maxlon[i] (i在直径上) 表示到i的路径不经过直径的 离i最远的点到i的距离

    这时核的偏心距就是max(maxlon[i],核的端点到直径的端点的长度) (i为核上的点)

    这样就能O(n)求解

    代码:

     1 #include <cstdio>
     2 const int N=301,M=1001;
     3 struct inli{
     4     int next,data,lon;
     5     inli(const int a=0,const int b=0,const int c=0):
     6         next(a),data(b),lon(c){}
     7 }line[N*2];
     8 int S,n,m,son[N],fat[N],dis[N],bo[N],maxlon[N],seclon[N],hard[N],nl;
     9 int max(int x,int y){ return x>y ? x : y;}
    10 int min(int x,int y){ return x<y ? x : y;}
    11 void makedis(int t){
    12     bo[t]=1;
    13     for (int i=son[t];i;i=line[i].next)
    14     if (!bo[line[i].data]){
    15         int ne=line[i].data;
    16         dis[ne]=dis[t]+line[i].lon;
    17         makedis(ne);
    18     }
    19 }
    20 void makefat(int t){
    21     for (int i=son[t];i;i=line[i].next)
    22     if (line[i].data!=fat[t]){
    23         int ne=line[i].data;
    24         fat[ne]=t;
    25         makefat(ne);
    26         if (maxlon[ne]+line[i].lon>maxlon[t]){
    27             seclon[t]=maxlon[t];
    28             maxlon[t]=maxlon[ne]+line[i].lon;
    29             hard[t]=i;
    30         }
    31     }
    32 }
    33 int makef(int x,int y){
    34     if (!x) return 0;
    35     int i=hard[x];
    36     if (y<line[i].lon) return maxlon[x];
    37     return max(seclon[x],makef(line[i].data,y-line[i].lon));
    38 }
    39 int getans(){
    40     int res=100000000;
    41     for (int i=S,x=seclon[S];i;x+=line[hard[i]].lon,i=line[hard[i]].data){
    42         if (x>res) break;
    43         res=min(res,max(makef(i,m),x));
    44     }
    45     return res;
    46 }
    47 int main(){
    48     scanf("%d%d",&n,&m);
    49     for (int x,y,z,i=1;i<n;i++){
    50         scanf("%d%d%d",&x,&y,&z);
    51         line[++nl]=inli(son[x],y,z),son[x]=nl;
    52         line[++nl]=inli(son[y],x,z),son[y]=nl;
    53     }
    54     makedis(1);
    55     int x=0;
    56     for (int i=1;i<=n;i++)
    57     if (dis[i]>x) x=dis[i],S=i;
    58     makefat(S);
    59     printf("%d",getans());
    60 }
    View Code
  • 相关阅读:
    PHP+VUE实现前端和后端数据互通(宝塔面板)
    PHP上传图片
    GIT常用命令
    基于Postman中的报错
    VUE项目Eslint报错
    git配置:本地仓库提交到远程仓库
    mybatis基础
    Json验证数据
    Json 三种格式数据解析
    Ajax 实现数据异步传输
  • 原文地址:https://www.cnblogs.com/g-word/p/3385217.html
Copyright © 2011-2022 走看看