树的直径,树形DP,DFS——POJ1958

Posted helman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的直径,树形DP,DFS——POJ1958相关的知识,希望对你有一定的参考价值。

题目链接

题目含义

就是建一个树,让你求最大直径

下面用分别用DP和DFS的方法

题目代码

技术图片
#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;
树形DP

树形DP的思想是用任意一个节点作为根

然后找出这个根的深度最大的两个子树

这两个子树的深度之和就是最大直径

技术图片
#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;
两次DFS

两次DFS的思想是先用任意一个节点作为根

找到离他最远的节点的深度ANS_MAX和这个节点的位置ANS_INDEX

然后再以找到的这个节点作为根

找出离他最远的节点的深度,与ANS_MAX做比较,就能找出最大直径

 

以上是关于树的直径,树形DP,DFS——POJ1958的主要内容,如果未能解决你的问题,请参考以下文章

树的直径

[树形dp] aw3760. 最大剩余油量(树的直径+树形dp+aw周赛007_3)

树的直径概念及求解

HDOJ2196Computer(树的直径,树形DP)

hdu2196 树形dp经典|树的直径

树的直径方法总结