hihocoder1224赛车(树的深度相关)

来源:互联网 发布:php 获取网页内容 编辑:程序博客网 时间:2024/06/10 04:04

题目连接:传送门 


题意:

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


分析:

如果可以加边的话那么这两个链一定是某个节点的最长链与次长链,然后一边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;}/***101 22 33 73 88 102 44 55 66 9***/


0 0
原创粉丝点击