标签:
幻想乡有一个赛车场。赛车场里有N个地点。同时地点之间还有单向的道路存在。
这些道路使得赛车场形成了一个外向树的结构。也就是说,道路将这N个地点连成了一个有根树。并且所有的边都是从父亲指向孩子的。
由于幽香喜欢刺激,每次她去赛车场都会从根节点出发,选择最长的一条路径来玩。
但是现在幽香感觉最长的路径还是太短了,她打算在赛车场里新建一条道路使得新的最长路径最长。
同时,如果道路形成了一个环,那么可能会出现交通事故,所以幽香新建的道路不能导致环的出现。
你能帮幽香算出新建一条道路后的最长路径吗?幽香知道根节点一定是1号点。
一行一个数N,表示地点的数量。
接下来N-1行,每行两个数a和b,表示从点a到点b有一条单向路径。所有点从1到n标号。
数据范围:
n<=100000。
一行表示新建一条边后的最长路径。
5 1 2 2 3 1 4 4 5
样例输出
4
解法:如果这个树是一条链,加一条边不能增加最长路径的长度,否则,答案就是最长路径+最长的与最长路径没有公共边的路径+1
#include <cstdio> #include <cstring> #include <string> #include <map> #include <vector> using namespace std; vector<int> e[100010]; int deep[100010]; int mL; int n; int sub_path; int dfs(int v){ deep[v] = 0; for(int i=0;i<e[v].size();i++){ int t = dfs(e[v][i]); if(t+1>deep[v]) deep[v] = t+1; } return deep[v]; } void findans(int v,int d){ for(int i=0;i<e[v].size();i++){ int u = e[v][i]; if(deep[u]+d==deep[1]){ int tm = 0; for(int j = 0;j< e[v].size();j++){ if(i==j) continue; if(deep[e[v][j]]>tm)tm = deep[e[v][j]]; } if(sub_path<tm) sub_path = tm; findans(u,d+1); } } } int main(){ scanf("%d",&n); int a,b; for(int i=1;i<n;i++){ scanf("%d%d",&a,&b); e[a].push_back(b); } sub_path = 0; dfs(1); findsub_path(1,1); sub_path+= sub_path!=0; printf("%d\n",sub_path+deep[1]); return 0; }
标签:
原文地址:http://www.cnblogs.com/zhjou/p/4771657.html