链接:https://www.nowcoder.com/acm/contest/136/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
桃花一簇开无主,可爱深红映浅红。
——《题百叶桃花》
桃花长在桃树上,树的每个节点有一个桃花,调皮的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
备注:
对于100%的测试数据: 1 ≤ n ≤ 1000000 数据量较大,注意使用更快的输入输出方式。
大致思路:
很容易想到求树的直径,即从任意节点开始dfs一次,找到最长链的一个节点。然后从这个节点出发找到另一个节点。这两个节点的距离最长。(用链式前向星一次就能ac,用vector容易卡在95%,但吸氧能过)
ac代码:
# pragma GCC optimize (3) //吸氧
# include <iostream>
# include <cstring>
# include <vector>
# include <cstdio>
# include <algorithm>
using namespace std;
const int MAXN = 1e6+10;
vector <int > v[MAXN];
bool book[MAXN];
int L,res=0;//L为最长链的一个节点
void dfs(int root,int cnt)
{
if(v[root].size()==1&&cnt>res)//没什么用的减枝
{
res=cnt;
L=root;
}
for(int i=0;i<v[root].size();i++)
{
int nx=v[root][i];
if(book[nx])
continue;
book[nx]=1;
dfs(nx,cnt+1);
}
return ;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
memset(book,0,sizeof book);
book[1]=1;
dfs(1,1);
memset(book,0,sizeof book);
book[L]=1;
res=0;
dfs(L,1);
cout<<res<<endl;
}