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

2019-07-30

树的直径,树形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,DFS——POJ1958

原文地址:https://www.cnblogs.com/helman/p/11271948.html