hihocoder1224 赛车(树的深度相关)

题目连接:传送门 


题意:

给你一棵树,然后加一条边,加的这条边不能使树成环,求加边后从根节点出发的最长的路径。


分析:

如果可以加边的话那么这两个链一定是某个节点的最长链与次长链,然后一边dfs处理出所有的节点的深度,然后再一遍dfs求出所有点的最长链的长度与次长链的长度,然后枚举节点就可以了。


代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 1e5+10;

vector<int > vc[maxn];

int dept[maxn];
int mmax;

void init(){
    for(int i=0;i<maxn;i++){
        vc[i].clear();
    }
    mmax=0;
}

void dfs(int u,int dep){
    dept[u]=++dep;
    mmax = max(dep,mmax);
    for(int i=0;i<vc[u].size();i++){
        int v=vc[u][i];
        dfs(v,dep);
    }
}

int m[maxn][2];

int slove(int u){
    if(m[u][0]) return m[u][0];
    int m1=dept[u],m2=0;
    for(int i=0;i<vc[u].size();i++){
        int tmp = slove(vc[u][i]);
        if(tmp<=m1&&tmp>m2&&m1!=dept[u]) m2=tmp;
        if(tmp>m1){
            if(m1!=dept[u])
                m2=m1;
            m1=tmp;
        }
    }
    m[u][0]=m1;
    m[u][1]=m2;
    return m1;
}

int main()
{
    int n;
    while(~scanf("%d",&n)){
        init();
        for(int i=0;i<n-1;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            vc[u].push_back(v);
        }
        memset(m,0,sizeof(m));
        dfs(1,0);
        slove(1);
        int ans = 0;
        for(int i=1;i<=n;i++){
            if(m[i][1])
                ans=max(ans,m[i][0]-1+m[i][1]-dept[i]);
        }
        if(!ans) printf("%d\n",mmax-1);
        else printf("%d\n",ans);
    }
    return 0;
}

/***
10
1 2
2 3
3 7
3 8
8 10
2 4
4 5
5 6
6 9
***/


你可能感兴趣的:(hihocoder1224 赛车(树的深度相关))