树的直径
Posted arbor-one
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树的直径相关的知识,希望对你有一定的参考价值。
dp
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<cstring>
using namespace std;
const int N=1000100;
int head[N],net[N],ans,ed[N],ver[N],tot,d[N];
bool v[N]={false};
void add(int x,int y,int z)
{
ver[++tot]=y,ed[tot]=z,net[tot]=head[x],head[x]=tot;
}
void dp(int x)
{
v[x]=1;
for(int i=head[x];i;i=net[i])
{
int y=ver[i];
if(v[y])continue;//判断是不是访问过这个节点
dp(y); //向下寻找子节点
ans=max(ans,d[x]+d[y]+ed[i]);//枚举从x节点出发的所有边,找到一个最远的路径,
d[x]=max(d[x],d[y]+ed[i]);//经过枚举后,d[x]就不一定是最长的了。要更新一下
}
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y,z;
cin>>x>>y>>z;//创建无向图
add(x,y,z);
add(y,x,z);
}
dp(1);
printf("%lld",ans);//处处最长路径
}
两边bfs
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
#include<stdio.h>
using namespace std;
const int N=1010000;
int head[N],ver[N],ed[N],net[N],tot;
int dist[N],v[N],maxd;
int n,p,q,d;
void add(int x,int y,int z)
{
ver[++tot]=y,ed[tot]=z,net[tot]=head[x],head[x]=tot;
}
int bfs(int u)
{
queue<int >q;
while(q.size())q.pop();//把队排空
memset(v,0,sizeof(v));
memset(dist,0,sizeof(dist));
q.push(u);//先把这个节点添加进去
int x,max_num=0;
while(!q.empty()){
x=q.front();q.pop();//取出队顶元素 然后抛出
v[x]=1;//已经访问过了置1
for(int i=head[x];i;i=net[i])//遍历这个节点及其子树
{
int y=ver[i];//下一个节点
if(v[y])continue;
v[y]=1;//没访问过置一
dist[y]=dist[x]+ed[i];//从上往下走,累加
if(dist[y]>maxd){//更新最大值和节点号
maxd=dist[y];
max_num=y;
}
q.push(y);//每个新的节点都要入队
}
}
return max_num;//最远节点的编号
}
int main()
{
cin>>n;
for(int i=1;i<n;i++)
{
cin>>p>>q>>d;//无向图 两边都加
add(p,q,d);
add(q,p,d);
}
int u=bfs(1);//从第一个节点开始选
int s=bfs(u);//第一个节点的最远节点的最远节点
cout<<maxd<<endl;//输出直径
return 0;
}
以上是关于树的直径的主要内容,如果未能解决你的问题,请参考以下文章