zoukankan      html  css  js  c++  java
  • 树的直径相关

    真的还有好多东西要学啊......

     

    定理:

      选取树 $T$ 的任意一个点 $i$ ,则与 $i$ 距离最远的节点 $r$ 必定是树中一条直径的端点.

     

    定理:

      经过树上一点i的最长路径的长度,一定等于:

      情况1. $i$ 所引领的子树中,最大深度与次大深度之和.

      情况2. $i$ 所引领的子树中的最大深度,加上 $i$ 到 $j$ 的最长路径,其中 $j$ 是一个不属于 $i$ 这个子树的节点.

      当 $i$ 是树根时, $i$ 没有父节点,于是只会是情况1.

     

    定理:

      树 $T$ 的直径长度一定能表示为树 $T$ 上某个点 $i$ 所引领的子树中,最大深度与次大深度之和.

      即, $exists_{iin V(T)}; diameter = LargestDepth(subtree o ! f i) + SecondLargestDepth(subtree o ! f i)$

      由于直径只有一个值,并且两个深度之和代表了一条路径的长度,

      于是有$forall_{iin V(T)} ; diameter ge LargestDepth(subtree o ! f i) + SecondLargestDepth(subtree o ! f i)$

     

    定理:

      点 $i$ 在某条直径上,当且仅当存在一条经过点 $i$ 的路径,它的长度(大于)等于直径.

     

    AC VIJOS 1476 求在直径上的所有点. 直径可能有多条.

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42  
     43 db eps=1e-80;
     44 inline bool feq(db a,db b)
     45 { return fabs(a-b)<eps; }
     46 
     47 template<typename Type>
     48 inline Type avg(const Type a,const Type b)
     49 { return a+((b-a)/2); }
     50 
     51 //===================================================================
     52 //===================================================================
     53 //===================================================================
     54 //===================================================================
     55 
     56 
     57 const int INF=(1<<30)-1;
     58 
     59 struct edge
     60 {
     61     int in;
     62     edge*nxt;
     63 }pool[405000];
     64 edge*et=pool;
     65 edge*eds[205000];
     66 void addedge(int i,int j)
     67 { et->in=j; et->nxt=eds[i]; eds[i]=et++; }
     68 #define FOREACH_EDGE(i,j) for(edge*i=eds[j];i;i=i->nxt)
     69 
     70 int n;
     71 
     72 int dep[205000];
     73 int q[205000],qh,qt;
     74 
     75 int deg[205000];
     76 
     77 int dia=0;
     78 
     79 int mx[205000];
     80 int mxs[205000];
     81 int mxp[205000];
     82 int uv[205000];
     83 
     84 int f[205000];
     85 
     86 int main()
     87 {
     88     n=getint();
     89     for(int i=1;i<n;i++)
     90     {
     91         int a=getint();
     92         int b=getint();
     93         addedge(a,b);
     94         addedge(b,a);
     95     }
     96     
     97     qh=qt=0;
     98     q[qt++]=0;
     99     memset(dep,0xFF,sizeof(int)*(n+1));
    100     dep[0]=0;
    101     while(qh!=qt)
    102     {
    103         int x=q[qh];
    104         FOREACH_EDGE(i,x)
    105         if(dep[i->in]==-1)
    106         {
    107             f[i->in]=x;
    108             dep[i->in]=dep[x]+1;
    109             q[qt++]=i->in;
    110             deg[x]++;
    111         }
    112         qh++;
    113     }
    114     
    115     memset(mxp,0xFF,sizeof(int)*(n+1));
    116     memset(mx,0xFF,sizeof(int)*(n+1));
    117     memset(mxs,0xFF,sizeof(int)*(n+1));
    118     qh=qt=0;
    119     for(int i=0;i<n;i++)
    120     if(deg[i]==0) q[qt++]=i;
    121     while(qh!=qt)
    122     {
    123         int x=q[qh];
    124         
    125         FOREACH_EDGE(i,x)
    126         if(i->in!=f[x])
    127         {
    128             if(mx[i->in]>mx[x])
    129             {
    130                 mxs[x]=mx[x];
    131                 mx[x]=mx[i->in];
    132                 mxp[x]=i->in;
    133             }
    134             else if(mx[i->in]>mxs[x])
    135             {
    136                 mxs[x]=mx[i->in];
    137             }
    138         }
    139         
    140         deg[f[x]]--;
    141         if(deg[f[x]]==0)
    142         { q[qt++]=f[x]; }
    143         
    144         mx[x]++;
    145         mxs[x]++;
    146         
    147         qh++;
    148     }
    149     
    150     qh=qt=0;
    151     uv[0]=0;
    152     FOREACH_EDGE(i,0)
    153     q[qt++]=i->in;
    154     
    155     while(qh!=qt)
    156     {
    157         int x=q[qh];
    158         
    159         uv[x]=max( uv[f[x]],
    160                  x==mxp[f[x]] ? mxs[f[x]] : mx[f[x]]) +1;
    161         
    162         FOREACH_EDGE(i,x)
    163         if(i->in!=f[x]) q[qt++]=i->in;
    164         
    165         qh++;
    166     }
    167     
    168     for(int i=0;i<n;i++)
    169     dia=max(dia,mx[i]+mxs[i]);
    170     
    171     
    172     for(int i=0;i<n;i++)
    173     if(mx[i]+uv[i]==dia || mx[i]+mxs[i]==dia) printf("%d
    ",i);
    174     
    175     return 0;
    176 }
    View Code

    自底向上DP的思路很巧妙.注意两个条件都要判断.

     

  • 相关阅读:
    AOP代理对象生成
    redis 3.2 新数据结构:quicklist、String的embstr与raw编码方式分界点
    关系数据库/分布式系统一致性模型
    JDK1.8 StampedLock: 解决ReentrantReadWriteLock在读多写少情况下,写线程饥饿问题
    JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现
    相对路径
    python用matplotlib画折线图
    python 信息同时输出到控制台与文件
    keras 设置GPU使用率
    python – 基于pandas中的列中的值从DataFrame中选择行
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4388518.html
Copyright © 2011-2022 走看看