求树的直径用dfs可做,每次返回以当前结点为终点、某个叶子为起点的最长路径长度,同时找最大的两条路径求和更新最优解。
具体分有多条同样长的最长路径、有一条最长路径和一条或多条次长路径、只有一条路径、叶子结点这几种情况。O(n)可做。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=100005;
int val[maxn],sz[maxn];
int best,num;
struct Edge
{
int to,cost;
Edge(int a,int b):to(a),cost(b) {}
};
vector<Edge> g[maxn];
int dfs(int now,int fa)
{
int maxi1=0,maxi2=0;
int cnt1=0,cnt2=0;
int n1=0,n2=0;
int rt1=0;
for(int i=0; i<g[now].size(); ++i)
{
int to=g[now][i].to,cst=g[now][i].cost;
if(to==fa)
continue;
int res=dfs(to,now)+cst;
if(maxi1<res)
{
maxi2=maxi1;
cnt2=cnt1;
n2=n1;
maxi1=res;