zoukankan      html  css  js  c++  java
  • luogu P3304 [SDOI2013]直径

    树的直径两遍dfs救星了

    至于一定在直径中的边数,可以发现这些边一定是连续的(不然你两条直径中间能有空挡?),然后,如果某个点往下有多条直径,那么这条点以下都不算入答案.所以以直径分别两端点为根,找出这样离根最近的点(注意最远的点就是另一个端点),然后找到那两个点的距离就是答案

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define max(a,b) ((a)>(b)?(a):(b))
    
    using namespace std;
    const int N=200000+10;
    il LL rd()
    {
        re LL x=0,w=1;re char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[N<<1],nt[N<<1],hd[N],tot=1;
    LL w[N<<1],di[N],f[N],lent;
    bool v[N];
    il void add(int x,int y,LL z)
    {
      ++tot;to[tot]=y;nt[tot]=hd[x];w[tot]=z;hd[x]=tot;
      ++tot;to[tot]=x;nt[tot]=hd[y];w[tot]=z;hd[y]=tot;
    }
    int n,fa[N];
    il int dfs(int x,int ffa)
    {
      int xx=0;
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(y==ffa) continue;
          fa[y]=x,di[y]=di[x]+w[i];
          int yy=dfs(y,x);
          if(di[xx]<di[yy]) xx=yy;
        }
      return xx?xx:x;
    }
    il int dd(int x,int ffa)
    {
      f[x]=0;
      int xx=0,cnt=0;
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(y==ffa) continue;
          int yy=dd(y,x);
          if(!xx) xx=yy;
          f[x]=max(f[x],f[y]+w[i]);
          if(di[x]+f[y]+w[i]==lent&&ffa) ++cnt;
        }
      return (cnt>1&&v[x])?x:xx;
      
    }
    
    int main()
    {
      int aa,bb,c,d,an=0;
      n=rd();
      for(int i=1;i<n;i++)
        {
          int x=rd(),y=rd(),z=rd();
          add(x,y,z);
        }
      aa=1;
      di[1]=fa[1]=0;aa=dfs(1,0);
      di[aa]=fa[aa]=0;bb=dfs(aa,0);
      lent=di[bb];
      int now=bb;
      while(now) v[now]=true,now=fa[now];
      c=dd(aa,0);if(!c) c=bb;
      di[bb]=fa[bb]=0,dfs(bb,0);
      d=dd(bb,0);if(!d) d=aa;
      while(d!=c) ++an,d=fa[d];
      printf("%lld
    %d
    ",lent,an);
      return 0;
    }
    
  • 相关阅读:
    人月神话阅读笔记01
    HTML中常用meta整理
    前端开发中的SEO
    webGL学习笔记
    webGL 学习教程
    HTMl5的sessionStorage和localStorage
    Validform使用
    gulp详细入门教程
    gulp.spriteSmith使用
    gulp.spritesmith修改px为rem单位
  • 原文地址:https://www.cnblogs.com/smyjr/p/9544922.html
Copyright © 2011-2022 走看看