正权边的树的直径
求正权边树的直径的算法:首先随机选一点dfs到最远端,此即为直径的其中一个端点;再从这个点出发dfs到最远端,即为直径的另一个端点。
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int N=100010,M=2*N;
int n;
int h[N],e[M],ne[M],w[M],idx; //邻接表
bool vis[N];
int maxu,maxd; //储存最远端点和最远距离
int add(int a,int b,int c) //从a到b连边,边权为c
{
e[++idx]=b,ne[idx]=h[a],h[a]=idx,w[idx]=c;
}
void dfs(int u,int d) //当前走到节点u,经过长度之和为d的边
{
vis[u]=true;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i],len=w[i];
if(vis[j])continue;
if(maxd<d+len)maxd=d+len,maxu=j; //当总距离比存储值更大,就更新
dfs(j,d+len); //继续向下搜索
}
}
int main()
{
cin>>n;
memset(h,-1,sizeof h);
for(int i=1;i<=n-1;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c),add(b,a,c);
}
dfs(1,0); //随机选一个点第一次dfs
memset(vis,0,sizeof vis);
dfs(maxu,0); //再来一次
cout<<maxd;
return 0;
}