树的直径模板

代码-树的直径

//solution dp
#include<bits/stdc++.h>
#define N 10010 
using namespace std; 
struct Edge{
     int u,v,next,w; 
}G[N*2]; 
int tot=0,head[4*N],dp1[N],dp2[N]; 
//dp1[u]:从u出发到子树内最长链
 //dp2[u]:从u出发,到与dp1不同的子树中,产生的次长链  
void addedge(int u,int v,int w){      G[++tot].u=u;G[tot].v=v;G[tot].w=w;
 G[tot].next=head[u];head[u]=tot;      G[++tot].u=v;G[tot].v=u;G[tot].w=w;
 G[tot].next=head[v];head[v]=tot; 
}

int ans=0; 

void work(int u,int fa){
    for (int i=head[u];i;i=G[i].next){
        int v=G[i].v,w=G[i].w;
        if (v==fa)continue;
        work(v,u);
        if (dp1[v]+w>dp1[u]){
            dp2[u]=dp1[u];
            dp1[u]=dp1[v]+w;
        }
        else dp2[u]=max(dp2[u],dp1[v]+w);
    }
//找出以u为结点,在u的两个不同子树中的最长和次长链组合起来就是找出的直径
    ans=max(dp1[u]+dp2[u],ans);
//比较更新当前最长直径
 }

int main(){
    int n;read(n);
    for (int i=1;i<n;i++){
        int u,v,w;
        read(u);read(v);read(w);
        addedge(u,v,w);
    }
    work(1,0);
    printf("%d\n",ans);
    return 0;
 }
//solution dfs
#include<bits/stdc++.h> 
const int N=1000010; 
using namespace std; 
int n,m,head[N],tot,dis[N],cur,mx; 
struct Edge{
    int u,v,w,next;
 }G[N<<1];

inline void addedge(int u,int v,int w){   
 G[++tot].u=u;G[tot].v=v;G[tot].w=w;
 G[tot].next=head[u];head[u]=tot;   
 G[++tot].u=v;G[tot].v=u;G[tot].w=w;
 G[tot].next=head[v];head[v]=tot;
 }

inline void dfs(int u,int fa){
    for(int i=head[u];i;i=G[i].next){
        int v=G[i].v;if(v==fa)continue;
        dis[v]=dis[u]+G[i].w;       
        if(dis[v]>mx)cur=v,mx=dis[v];
        dfs(v,u);
    }
 } 

int main(){
    n=read();
    for(int i=1;i<n;i++){
        int u=read(),v=read(),w=read();
        addedge(u,v,w);
    }
    dfs(1,0);
    mx=0;
    memset(dis,0,sizeof(dis));   
    dfs(cur,0);
    printf("%d\n",mx);
}
posted @ 2018-02-23 13:21  Neworld1111  阅读(245)  评论(0编辑  收藏  举报