zoukankan      html  css  js  c++  java
  • [hihocoder 1050]求树的最长链

    题目链接: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;
    }
  • 相关阅读:
    加载图片出现403的问题
    js字符串首字母大写的不同写法
    vue中使用两个window.onresize问题解决
    vue备用
    vue注册全局组件
    Java中Timer的用法
    笔记本设置wifi热点
    UVA 11401 Triangle Counting
    数论专题---除法表达式之高精度运算,扩展欧几里得算法
    能被2、3、4、5、6、7、8、9整除数的特征
  • 原文地址:https://www.cnblogs.com/acmsong/p/7666863.html
Copyright © 2011-2022 走看看