码迷,mamicode.com
首页 > 其他好文 > 详细

[hihocoder 1050]求树的最长链

时间:2017-10-14 14:39:19      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:ace   方法   scanf   两种   ref   lca   using   target   http   

题目链接:http://hihocoder.com/problemset/problem/1050

两种方法:

1. 两遍dfs,第一次随便找一个根,找到距离这个根最远的点,这个点必然是最长链的一端。第二次就用这个端点做一遍dfs,最远的点就是另一端。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int d[maxn];
vector<int> G[maxn];

void dfs(int u,int fa,int now)
{
    d[u]=now;
    for (int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if (v!=fa) dfs(v,u,now+1);
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    for (int i=0;i<n-1;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,0,0);
    int ma=0,maj=1;
    for (int i=1;i<=n;i++)
    {
        if (d[i]>ma)
        {
            ma=d[i];
            maj=i;
        }
    }
    dfs(maj,0,0);
    int ans=0;
    for (int i=1;i<=n;i++) ans=max(ans,d[i]);
    printf("%d",ans);
    return 0;
}

2. 树形dp。记dp[i][0/1]表示以i为lca的最长链和次长链的长度,一遍dfs更新就好了。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int dp[maxn][2];
vector<int> G[maxn];

void dfs(int u,int fa)
{
    for (int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if (v!=fa) dfs(v,u);
    }
    if (G[u].size()<=2)
    {
        for (int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if (v!=fa) dp[u][0]=dp[v][0]+1;
        }
    }
    else
    {
        for (int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if (v!=fa)
            {
                if (dp[v][0]+1>dp[u][0])
                {
                    dp[u][1]=dp[u][0];
                    dp[u][0]=dp[v][0]+1;
                }
                else dp[u][1]=max(dp[v][0]+1,dp[u][1]);
            }
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    G[1].push_back(0);
    for (int i=0;i<n-1;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,0);
    int ans=0;
    for (int i=1;i<=n;i++) ans=max(ans,dp[i][0]+dp[i][1]);
    printf("%d",ans);
    return 0;
}

 

[hihocoder 1050]求树的最长链

标签:ace   方法   scanf   两种   ref   lca   using   target   http   

原文地址:http://www.cnblogs.com/acmsong/p/7666863.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!