代码改变世界

hihoCoder挑战赛14,题目2 : 赛车

2015-08-30 21:11  iun  阅读(185)  评论(0编辑  收藏  举报

题目2 : 赛车

时间限制:20000ms
单点时限:1000ms
内存限制:256MB

描述

幻想乡有一个赛车场。赛车场里有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;
}