• hdoj3534(树形dp,求树的直径的条数)


    题目链接:https://vjudge.net/problem/HDU-3534

    题意:给出一棵树,求树上最长距离(直径),以及这样的距离的条数。

    思路:如果只求直径,用两次dfs即可。但是现在要求最长距离的条数,用dp1[u]记录以u为根的子树中叶子结点到u的最长距离,dp2[u]表示最长距离的条数,这两个比较容易维护。dfs过程中更新答案,用ans1表示树上直径,ans2表示该直径的条数,当dp1[v]+w+dp1[u]>ans1时更新。

    AC代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int maxn=1e4+5;
    typedef long long LL;
    int n,cnt,head[maxn];
    LL ans1,ans2,dp1[maxn],dp2[maxn];
    
    struct node{
        int v,w,nex;
    }edge[maxn<<1];
    
    void adde(int u,int v,int w){
        edge[++cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].nex=head[u];
        head[u]=cnt;
    }
    
    void dfs(int u,int fa){
        dp1[u]=0,dp2[u]=1;
        for(int i=head[u];i;i=edge[i].nex){
            int v=edge[i].v,w=edge[i].w;
            if(v==fa) continue;
            dfs(v,u);
            int tmp=dp1[v]+w;
            if(tmp+dp1[u]>ans1){
                ans1=tmp+dp1[u];
                ans2=dp2[u]*dp2[v];
            }
            else if(tmp+dp1[u]==ans1){
                ans2+=dp2[u]*dp2[v];
            }
            if(tmp>dp1[u]){
                dp1[u]=tmp;
                dp2[u]=dp2[v];
            }
            else if(tmp==dp1[u]){
                dp2[u]+=dp2[v];
            }
        }
    }
    
    int main(){
        while(~scanf("%d",&n)){
            cnt=ans1=ans2=0;
            for(int i=1;i<=n;++i)
                head[i]=0;
            for(int i=1;i<n;++i){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                adde(u,v,w);
                adde(v,u,w);
            }
            dfs(1,0);
            printf("%lld %lld
    ",ans1,ans2);
        }
        return 0;
    }

    顺便附上只用两次dfs求直径的代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    typedef long long LL;
    const int maxn=1e4+5;
    int n,cnt,head[maxn];
    LL dp1[maxn],dp2[maxn];
    
    struct node{
        int v,w,nex;
    }edge[maxn<<1];
    
    void adde(int u,int v,int w){
        edge[++cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].nex=head[u];
        head[u]=cnt;
    }
    
    void dfs(int u,int fa){
        dp1[u]=0;
        int flag=0;
        for(int i=head[u];i;i=edge[i].nex){
            int v=edge[i].v,w=edge[i].w;
            if(v==fa) continue;
            flag=1;
            dfs(v,u);
            if(dp1[v]+w>dp1[u]){
                dp1[u]=dp1[v]+w;
                dp2[u]=dp2[v];
            }
        }
        if(!flag) dp2[u]=u;
    }
    
    int main(){
        while(~scanf("%d",&n)){
            cnt=0;
            for(int i=1;i<=n;++i)
                head[i]=0;
            for(int i=1;i<n;++i){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                adde(u,v,w);
                adde(v,u,w);
            }
            dfs(1,0);
            int tmp=dp2[1];
            dfs(tmp,0);
            printf("%lld
    ",dp1[tmp]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    luncence
    git与svn与github与码云的区别
    redis缓存在项目中的使用
    大宗风控体系“药不能停”:一线实战高手解密衍生品交易风险管控的三个层级!
    永恒的风控:大宗商品贸易融资背后的核心风险该如何规避?
    达信:深度解读COSO新版企业风险管理框架(ERM)
    DataOps Reading Notes
    SDN Reading Notes
    给某mooc站点准备的FE大纲
    《财富》杂志推荐的75本商业必读书?
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11705888.html
Copyright © 2020-2023  润新知