桃花一簇开无主,可爱深红映浅红。
——《题百叶桃花》
桃花长在桃树上,树的每个节点有一个桃花,调皮的HtBest想摘尽可能多的桃花。HtBest有一个魔法棒,摘到树上任意一条链上的所有桃花,由于HtBest法力有限,只能使用一次魔法棒,请求出Htbest最多可以摘到多少个桃花。
输入描述:
第一行有一个正整数n,表示桃树的节点个数。
接下来n-1行,第i行两个正整数ai,bi ,表示桃树上的节点ai,bi之间有一条边。
输出描述:
第一行一个整数,表示HtBest使用一次魔法棒最多可以摘到多少桃花。
示例1
输入
复制
3
1 2
2 3
输出
复制
3
示例2
输入
复制
3
1 2
1 3
输出
复制
3
示例3
输入
复制
4
1 2
2 3
3 4
输出
复制
4
这道题一道非常经典的树的最长路径的题,需要用到 vector 来存
f1 f2 为最长边和次长边 什么是f1,f2相加呢? 看下图
它是以 1 为出发点 我们要求的是树最长直径 那么应该是左子树+右子树 这样求得才是总得结果 为什么还要+1 是因为没有本身
解释一下核心代码吧:
void dfs(int u,int per)
{
//用1-2-3-4举例 当一直跑到4这个点的时候
int k=g[u].size();// k=1;
for(int i=0;i<k;i++)
{
if(g[u][i]==per)//3 = 3 推出
continue;
dfs(g[u][i],u);//(4,3)//(3,2)
if(f1[g[u][i]]+1>=f1[u])//f1[4]+1>=f1[3]
{
f2[u]=f1[u];//f2[3]=f1[3]=0;
f1[u]=f1[g[u][i]]+1;//f1[3]=f1[4]+1;
}
else
{
f2[u]=max(f1[g[u][i]+1]+1,f2);
}
}
ans=max(ans,f1[u]+f2[u]+1);//ans=1
}
然后就是递推了 应该好理解一些
#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <vector>
#define ll long long
#define pi acos(-1.0)
using namespace std;
vector<int>g[1000010];
int ans=0;
int f1[1000010],f2[1000010];
void dfs(int u,int per)
{
int k=g[u].size();
for(int i=0;i<k;i++)
{
if(g[u][i]==per)//当子节点和父节点 相同时跳出
continue;
dfs(g[u][i],u);
if(f1[g[u][i]]+1>=f1[u])
{
f2[u]=f1[u];
f1[u]=f1[g[u][i]]+1;
}
else
{
f2[u]=max(f1[g[u][i]+1]+1,f2);
}
}
ans=max(ans,f1[u]+f2[u]+1);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<t;i++)
{
int a,b;
scanf("%d%d",&a,&b);
g[a].push_back(b);// 因为它是一个无向图 所以需要两边都存
//举例:如果它输入 2,1 3,1
g[b].push_back(a);
}
dfs(1,0);// 0 为父节点,1为子节点
printf("%d\n",ans);
}