1.最朴素的求法:
枚举每一个点作为起点找到离它最远的那个点(dfs),取每个点的最长路径的max
时间复杂度: O(n*n)
代码这里不贴咯
2.树形dp
对于点作为根,它的最长路径是他的最长路径和次长路径的和。所以对数进行树形dp:dp[x][0]->最长, dp[x][1]->次长。
dp[x][1]+dp[x][0]即为以此点为根的最长路径。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=100005;
struct node
{
int w,v;
};
vector<node> v[maxn];
node tmp;int ans=0;
int f[maxn][2];
void find(int x,int fa)
{
for(int i=0;i<v[x].size();i++)
{
int w=v[x][i].w;int p=v[x][i].v;
if(p==fa) continue;
find(p,x);
if(f[p][0]+w>f[x][0])
{
f[x][1]=f[x][0];
f[x][0]=f[p][0]+w;
}
else if(f[p][0]+w>f[x][1]) f[x][1]=f[p][0]+w;
}
ans=max(ans,f[x][1]+f[x][0]);
}
int main()
{
int n,k;scanf("%d%d",&n,&k);
for(int i=1;i<n;i++)
{
int a,b;scanf("%d%d",&a,&b);
tmp.w=1;tmp.v=b;
v[a].push_back(tmp);
tmp.v=a;v[b].push_back(tmp);
}
find(1,0);
printf("%d",(n-1-ans)*2+ans+1);
return 0;
}
3.先任意以一个点为根,找到离他最远的点,然后这个点必定是直径一个端点,以它为端点进行dfs(bfs)到的最远点必定为树的直径。
void find(int x,int fa,int dep)
{
if(maxv<dep) {maxv=dep;u=x;}
for(int i=0;i<v[x].size();i++)
{
if(v[x][i].v!=fa) find(v[x][i].v,x,dep+v[x][i].w);
}
}
void bfs(int s)
{
q.push(s);
//vis[s]=1;
f[s]=0;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<v[x].size();i++)
{
int tmp=v[x][i].v;
if(tmp!=f[x])
{
f[tmp]=x;
q.push(tmp);
deep[tmp]=deep[x]+1;
//maxv=max(maxv,deep[tmp]);
if(maxv<deep[tmp])
{
maxv=deep[tmp];t=tmp;
}
}
}
}
}