树得直径

树的直径

DP做法(一次DFS):

  1. 首先dfs每一个点
  2. 对每个点求一个最大值和次大值
  3. 每个点将最大值+次大值与ans比较得到解

代码:

const int N = 1e5+5;
const int M = 2e6+5;
typedef long long intl;//类型转换 
intl hd[N],nt[M],to[M],co[M],num=0,as=0;
intl dfs(intl u,intl pre){
    intl d1=0,d2=0,d;
    for(intl i=hd[u];i;i=nt[i]){
        intl v=to[i];
        if(v==pre) continue;
        d=dfs(v,u)+co[i];
        if(d>d1){
            d2=d1;
            d1=d;
        }
        else if(d>d2) d2=d;
    }
    as=max(as,d1+d2);
    return d1;
}

两次dfs:

  1. 随机从一个点u出发返回离u距离最远得v点
  2. 重v点出发,返回里最远得w点
  3. v-w的距离就是直径

代码:

const int N = 1e5+5;
const int M = 2e6+5;
typedef long long intl;//类型转换 
intl hd[N],nt[M],to[M],co[M],num=0,as=0,st,net[N];//as是直径
intl dfs(intl u,intl pre){
    intl d1=0,d;
    net[u]=u;
    for(intl i=hd[u];i;i=nt[i]){
        intl v=to[i];
        if(v==pre) continue;
        d=dfs(v,u)+co[i];
        if(d>d1){
            d1=d;
            net[u]=net[v];
        }
    }
    d1=max(d1,as);
    return d1;
}
int main(){
    dfs(1,-1);
    dfs(net[1],-1);
}

 

posted @ 2020-08-02 11:43  Grisaia  阅读(85)  评论(0)    收藏  举报