博客
关于我
动态规划求树的最大连通分支问题
阅读量:806 次
发布时间:2019-03-25

本文共 2017 字,大约阅读时间需要 6 分钟。

树的最大连通分支权和计算

题目概述

在给定一棵树T的情况下,每个顶点u都有权值w(u),可以是负数。任务是要找到树T的一个连通子图,使得该子图的权之和最大。

问题描述

对给定的树T,计算树T的最大连通分支。

算法设计

对于给定的树T,计算树T的最大连通分支。

数据输入

第1行有1个正整数n,表示树T有n个顶点。树T的顶点编号为1,2,…,n。第2行有n个整数,表示n个顶点的权值。接下来的n-1行中,每行有表示树T的一条边的2个整数u和v,表示顶点u与顶点v相连。

输入示例

5-1 1 3 1 -14 11 31 24 5

输出示例

4

算法分析

问题特点

  • 权值之和是树的属性,可以从每个叶节点沿分支累加到根。
  • 树的根是任意的,连通分支中的任何一个节点都可以作为根节点。
  • 权值和加起来最大的连通分支,其权重和可以累加到该分支的任意一个节点。
  • 解题策略

  • 最大连通分支是由多个子分支构成的树A,其权值和等于根的权值加上各个子分支的权值和。
  • 对于权值和>0的子分支,应尽可能大。
  • 要将问题分解为树中每个小树的最大连通分支的求解。
  • 解决思路

  • 分层选择根节点:选择一个根节点x,以x为根节点进行树的分层。
  • 自底向上遍历:从叶节点向根节点遍历,累加权值。
  • 计算最优解:在遍历树过程中,找到权值和最大的节点。
  • 样例解析

    以示例中的树为例,取节点1为根节点,分层后权值累加过程如下:

    • 关键点:从底至上,权值和为正的节点贡献给其父节点。
    • 样例结果:节点1的权值和为4。

    算法实现

    分层实现

  • 使用广度优先搜索(BFS)层次遍历树。
  • 记录每个节点的父节点和当前层次。
  • 将根节点(如节点1)作为起点,分层后得到层次结构。
  • 权值累加

  • 从叶节点(底层)进行权值处理。
  • 如节点权值小于0,贡献0给父节点;如大于0,则将值加给父节点。
  • 核心代码

    #include 
    #include
    #include
    #include
    #include
    using namespace std;struct node { int w; int parent; int level; bool visit; node() { w = 0; parent = 0; level = 0; visit = false; }};vector
    > adjList;void bfs() { queue
    q; list
    l; q.push(1); node[1].visit = true; while (!q.empty()) { int cur = q.front(); q.pop(); l = adjList[cur]; for (auto iter = l.begin(); iter != l.end(); ++iter) { int nxt = *iter; if (!node[nxt].visit) { node[nxt].visit = true; node[nxt].parent = cur; node[nxt].level = node[cur].level + 1; q.push(nxt); } } }}int main() { int n, i; cin >> n; adjList.assign(n+1, list
    ()); node assignNode(n+1, node()); for (i=1; i<=n; ++i) { cin >> node[i].w; } for (i=0; i < n-1; ++i) { int l, r; cin >> l >> r; adjList[l].push_back(r); adjList[r].push_back(l); } bfs(); while (!rank.empty()) { int cur = rank.top(); rank.pop(); int par = node[cur].parent; node[par].w += (node[cur].w > 0) ? node[cur].w : 0; } int max_w = node[1].w; int maxNode = 1; for (i=2; i<=n; ++i) { if (node[i].w > max_w) { max_w = node[i].w; maxNode = i; } } cout << "该树的最大连通分支的权值和是:" << max_w << '\n'; return 0;}

    结论

    通过以上方法,可以高效地计算出树的最大连通分支权值和。

    转载地址:http://tzdyk.baihongyu.com/

    你可能感兴趣的文章
    划分子网与NAT的区别。。。
    查看>>
    钻石操作符使用升级
    查看>>
    设置方法区大小与OOM
    查看>>
    对象的实例化内存布局与访问定位内容
    查看>>
    React + 导入模块的一个错误
    查看>>
    Laravel 直接返回404页面
    查看>>
    记一次内部系统渗透测试:小漏洞组合拳
    查看>>
    常用元素操作的方法
    查看>>
    命名实体识别数据预处理
    查看>>
    分布式是登录机制是如何实现的。
    查看>>
    解决 matplotlib 中文显示乱码的问题
    查看>>
    解决打开 json 文件中文乱码的问题
    查看>>
    计算机网络基础:DHCP服务的部署
    查看>>
    计算机网络基础:DNS 部署与安全
    查看>>
    计算机网络基础:NAT 网络地址转换
    查看>>
    计算机网络基础:PKI(公钥基础设施)
    查看>>
    计算机网络基础:VLAN(虚拟局域网)
    查看>>
    计算机网络基础:文件共享服务器(注册表更改)
    查看>>
    计算机网络基础:用户和组管理
    查看>>
    计算机网络基础:简单渗透
    查看>>