dfs求树的直径JAVA_树形dp求树直径、两次dfs求树直径

本文介绍了两种方法来求解树的直径问题,包括树形DP和两次深度优先搜索(DFS)。首先展示了使用树形DP的Java实现,通过遍历每个节点并更新以该节点为根的子树的最长路径。接着,提供了两次DFS的C++实现,首先找到最深的节点,然后从这个节点出发再次进行DFS以找到树的直径。
摘要由CSDN通过智能技术生成

树形dp求树直径:

#include#include#define ll long long

using namespace std;

const int N=100010,M=1000010;

int head[N];

int ver[M];

int edge[M];

int Next[M];

bool v[N];

int tot;

void add(int x,int y,int z)

{

ver[++tot]=y;

edge[tot]=z;

Next[tot]=head[x];

head[x]=tot;

}

ll ans;

int d[N];//以N为根节点在其子树的最长路

void dp(int x)//根节点

{

v[x]=1;

for(int i=head[x];i;i=Next[i])

{

int y=ver[i];

if(v[y])continue;

dp(y);

if(d[x]+d[y]+edge[i]>ans)ans=d[x]+d[y]+edge[i];//这两个if的顺序不要弄错

if(d[y]+edge[i]>d[x])d[x]=d[y]+edge[i];//

}

}

int main()

{

int n;//节点数

int m;//边数

while(cin>>n>>m)

{

ans=-9999999999;

for(int i=1;i<=m;++i)

{

int x,y,z;

cin>>x>>y>>z;

add(x,y,z);

add(y,x,z);

}

dp(1);

cout<

两次dfs求树直径:

#include#define ll long long

using namespace std;

const int N=100010,M=1000010;

int head[N];

int ver[M];

int edge[M];

int Next[M];

int tot;

priority_queue< pair>Q;

void add(int x,int y,int z)

{

ver[++tot]=y;

edge[tot]=z;

Next[tot]=head[x];

head[x]=tot;

}

ll ans;//记录最深的点的节点标号;

int d[N];//以N为根节点的子树的深度;

bool v[N];//无向图防止子节点回到父节点

void dfs(int x)

{

v[x]=1;

for(int i=head[x];i;i=Next[i])

{

int y=ver[i];

if(v[y])continue;

d[y]=d[x]+1;//从上往下加一即可;

if(d[y]>d[ans])ans=y;

dfs(y);

}

}

int main()

{

int n;//节点数

int m;//边数

while(cin>>n>>m)

{

ans=0;

d[0]=0;

for(int i=1;i<=m;++i)

{

int x,y,z;

cin>>x>>y>>z;

add(x,y,z);

add(y,x,z);

}

dfs(1);

memset(d,0,sizeof(d));//两次dfs注意清空搜索标记数组、子树深度数组d;

memset(v,0,sizeof(v));

//cout<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值