Tree Diameter, Tree DP, DFS - POJ1958

Keywords: PHP

Title Link

Topic Meaning

It's building a tree so you can get the maximum diameter

Here's how to use DP and DFS, respectively

Title Code

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=5e4+7;
int n,m,tot,a,b,c,ans;
char cc;
int head[maxn],d[maxn];
struct node{
    int to,w,next;
}edge[maxn*2];
void add(int u,int v,int w){
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int fa){
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa)continue;
        dfs(v,u);
        ans=max(ans,d[u]+d[v]+edge[i].w);
        d[u]=max(d[u],d[v]+edge[i].w);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    tot=0;
    memset(d,0,sizeof(d));
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++){
        scanf("%d%d%d %c",&a,&b,&c,&cc);
        add(a,b,c);add(b,a,c);
    }
    ans=0;
    dfs(1,0);
    printf("%d\n",ans);
    return 0;
}
Tree DP

The idea of a tree DP is to use any node as the root

Then find the two subtrees with the deepest depth of this root

The sum of the depths of the two subtrees is the maximum diameter

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn=5e4+7;
int n,m,tot,a,b,c,ans;
char cc;
int head[maxn],dis[maxn];
struct node{
    int to,w,next;
}edge[maxn*2];
void add(int u,int v,int w){
    edge[tot].to=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int fa){
    for(int i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(v==fa)continue;
        dis[v]=dis[u]+edge[i].w;
        dfs(v,u);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    tot=0;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++){
        scanf("%d%d%d %c",&a,&b,&c,&cc);
        add(a,b,c);add(b,a,c);
    }
    int ans_max=0,ans_index=0;
    memset(dis,0,sizeof(dis));
    dfs(1,0);
    for(int i=1;i<=n;i++){
        if(dis[i]>ans_max){
            ans_max=dis[i];
            ans_index=i;
        }
    }
    memset(dis,0,sizeof(dis));
    dfs(ans_index,0);
    for(int i=1;i<=n;i++)
        if(dis[i]>ans_max)
            ans_max=dis[i];
    printf("%d\n",ans_max);
    return 0;
}
Twice DFS

The idea of twice DFS is to use any node as the root first

Find the depth of the node farthest from him and the position of the node ANS_INDEX

Then use the node found as the root

Find the depth of the farthest node from him and compare it with ANS_MAX to find the maximum diameter

Posted by liquorvicar on Tue, 30 Jul 2019 13:20:47 -0700