zoukankan      html  css  js  c++  java
  • hdu3899(树形dp)

    题意:给一树,每个结点有人数,边有权值,表示经过这条边所需时间, 问取某个结点作为开会地点,所有人全部到达此结点最少所需总时间? 

    分析:val[u]表示以u为根节点的总人数,num[u]表示以u为根节点的总用时,可以先做一次dfs算出树上所有点到根节点(1)的花费总和,然后同时计算出num[u],然后就是又一次dfs算出以每个点为根的话费,这里有dp[v]=num[v]+(sum-val[v])*w+(dp[u]-num[v]-(val[v]*w));(其中u是v的根)。简单题不多说。

    注意一点:这题会爆栈,需要加上这句#pragma comment(linker,"/STACK:102400000,102400000")并用C++提交

    #pragma comment(linker,"/STACK:102400000,102400000")
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define N 100010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    using namespace std;
    struct edge
    {
        int v,w,next;
        edge(){}
        edge(int v,int w,int next):v(v),w(w),next(next){}
    }e[2*N];
    int head[N*2],tot,n;
    LL val[N],num[N],dp[N],sum;
    void addedge(int u,int v,int w)
    {
        e[tot]=edge(v,w,head[u]);
        head[u]=tot++;
    }
    void dfs1(int u,int fa)
    {
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].v,w=e[i].w;
            if(v==fa)continue;
            dfs1(v,u);
            num[u]+=num[v]+val[v]*(LL)w;
            val[u]+=val[v];
        }
    }
    void dfs2(int u,int fa)
    {
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].v,w=e[i].w;
            if(v==fa)continue;
            dp[v]=num[v]+(sum-val[v])*(LL)w+(dp[u]-num[v]-(val[v]*(LL)w));
            dfs2(v,u);
        }
    }
    int main()
    {
        int u,v,w;
        while(scanf("%d",&n)>0)
        {
            FILL(head,-1);FILL(num,0);tot=0;sum=0;
            for(int i=1;i<=n;i++)scanf("%d",&val[i]),sum+=val[i];
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
            dfs1(1,-1);
            dp[1]=num[1];
            dfs2(1,-1);
            LL ans=1LL<<50;
            for(int i=1;i<=n;i++)ans=min(ans,dp[i]);
            printf("%I64d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    vue 组件轮播联动
    Echarts 解决饼图文字过长重叠的问题
    Echarts 背景渐变柱状图
    vue 组件间数据传递
    vue webpack build 打包过滤console.log()日志
    自定义字段排序
    vue 路由嵌套高亮问题
    微信小程序验证码获取倒计时
    解决小程序里面的图片之间有空隙的问题???
    axios使用
  • 原文地址:https://www.cnblogs.com/lienus/p/4207471.html
Copyright © 2011-2022 走看看