Computer

本文介绍了一种使用树形DP解决每个节点可达最远距离问题的方法。通过定义状态dp[u][0]表示节点u在其子树内能到达的最远距离,dp[u][1]表示次远距离,dp[u][2]表示经过父节点的最远距离。采用两次DFS算法,先计算子树内的最远距离,再更新经过父节点的最远距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Computer (树形dp)

给你一棵树,问你每个点能到达的最远距离。N<=10000。

这是道树形dp入门题(流下伤心的泪水)首先一个结点,它能到的最远点要么在子树内,要么在子树外。我们根据这个来搞dp。\(dp[u][0]\)表示在u的子树内,u能到达的最远距离。\(dp[u][1]\)则表示子树内的次远距离。\(dp[u][2]\)表示u经过它的父亲的最远距离。首先\(dp[u][0]\)\(dp[u][1]\)是容易求的。然后我们考虑经过父亲的情况,设u是v的父亲,那么\(dp[v][2]=max(dp[u][2], dp[v][0]+w[i]==dp[u][0]?dp[u][1]:dp[u][0])\)

我还考虑了这样的情况:情况。我蠢蠢的认为这样子的情况,\(dp[u][1]\)用我的代码求出来是0,是不行的。然而。。它就应该是0。因为你走了u就不能走回头路了。所以\(dp[u][1]\)的定义不应该是u这个节点走到子树中任意一个点的的次大距离,而应该是在所有经过子节点i的最大路径中次大的哪一个。蛤蛤,真是为自己的智商感到担忧。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=10005;

class Graph{
public:
    struct Edge{
        int to, next, v; Graph *bel;
        void set(int x, int y, Graph *g){
            to=x; next=y; bel=g; }
        inline int operator *(){ return to; }
        Edge& operator ++(){
            return *this=bel->edge[next]; }
    };
    void reset(){ //edge不用清零,因为最后跳到的结点是0
        memset(fir, 0, sizeof(fir));
        cntedge=0; edge[cntedge].to=0;
    }
    void addedge(int x, int y, int w){
        edge[++cntedge].set(y, fir[x], this);
        fir[x]=cntedge; edge[cntedge].v=w;
    }
    Edge& getlink(int x){ return edge[fir[x]]; }
private:
    int cntedge, fir[maxn];
    Edge edge[maxn*2];
};

Graph g;
int n, dp[maxn][3];

void dfs1(int now, int par){
    Graph::Edge e=g.getlink(now);
    int tmp;
    for (; *e; ++e){
        if (*e==par) continue;
        dfs1(*e, now);
        tmp=dp[*e][0]+e.v;
        if (tmp>=dp[now][0]){
            dp[now][1]=dp[now][0];
            dp[now][0]=tmp;
        } else if (tmp>dp[now][1])
            dp[now][1]=tmp;
    }
}

void dfs2(int now, int par){
    Graph::Edge e=g.getlink(now);
    for (; *e; ++e){
        if (*e==par) continue;
        dp[*e][2]=max(dp[now][2],
                dp[*e][0]+e.v==dp[now][0]?
                    dp[now][1]:dp[now][0])+e.v;
        dfs2(*e, now);
    }
}

int main(){
    while (~scanf("%d", &n)){
        memset(dp, 0, sizeof(dp));
        int x, y; g.reset();
        for (int i=2; i<=n; ++i){
            scanf("%d%d", &x, &y);
            g.addedge(i, x, y); g.addedge(x, i, y);
        }
        dfs1(1, 0);
        dfs2(1, 0);
        for (int i=1; i<=n; ++i)
            printf("%d\n", max(dp[i][0], dp[i][2]));
    }
}

转载于:https://www.cnblogs.com/MyNameIsPc/p/7744814.html

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值