There is a racing track in Gensokyo.
The racing track is a directed tree with n nodes in which the direction of each are from the father to the son.
Yuuka wants to pick a longest path in the tree but she is not satisfied with the current track.
So she decides to add an edge to make the new longest path longest but adding the new edge can't bring a loop in the tracks because of the security problem.
Yuuka will always start from Node 1 which is the root of the tree.
One line with an integer n, denoting the number of the nodes.
Following n-1 lines, each line with two numbers a and b, denoting there is an edge from a to b.
Data Limit:
N<=100000.
One line with an integer which is the answer.
5 1 2 2 3 1 4 4 5
4
题意:一棵有向树,请添加一条边获得最长的路径,前提不能成环。
思路:显然找最长路和次长路(要两者无交集),那么先反向建树找出叶子到根的全部距离,排序后,再找一次叶子到根的距离,这次的路径不能有交集了,最后再排序一次,取前两个加起来就行。
# include <iostream>
# include <cstdio>
# include <vector>
# include <cstring>
# include <algorithm>
using namespace std;
const int maxn = 1e5+8;
vector<int>g[maxn];
int id[maxn]={0,1};
int h[maxn],used[maxn]={0};
int dfs1(int cur)
{
if(cur == 1 || used[cur]) return used[cur];
used[cur] = dfs1(g[cur][0]) + 1;
return used[cur];
}
int dfs2(int cur)
{
if(cur == 1 || used[cur]) return 0;
used[cur] = dfs2(g[cur][0]) + 1;
return used[cur];
}
bool cmp(int x, int y) {return h[x] > h[y];}
int main()
{
int n, x, y;
scanf("%d",&n);
for(int i=1; i<n; ++i)
{
scanf("%d%d",&x,&y);
g[y].push_back(x);
}
for(int i=2; i<=n; ++i)
id[i]=i, h[i] = dfs1(i);
sort(id+1,id+n+1, cmp);
memset(used, 0, sizeof(used));
for(int i=1; i<=n; ++i)
{
int j = id[i];
h[j] = dfs2(j);
}
sort(h+1, h+1+n, greater<int>());
printf("%d\n",h[1]+h[2]);
return 0;
}