博客
关于我
动态规划求树的最大连通分支问题
阅读量: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/

    你可能感兴趣的文章
    Nginx配置实例-反向代理实例:根据访问的路径跳转到不同端口的服务中
    查看>>
    Nginx配置实例-反向代理实现浏览器请求Nginx跳转到服务器某页面
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    Nginx配置文件nginx.conf中文详解(总结)
    查看>>
    Nginx配置自带的stub状态实现活动监控指标
    查看>>
    nginx配置详解、端口重定向和504
    查看>>
    Nginx配置负载均衡到后台网关集群
    查看>>
    Nginx配置限流,技能拉满!
    查看>>
    Nginx配置静态代理/静态资源映射时root与alias的区别,带前缀映射用alias
    查看>>
    Nginx面试三连问:Nginx如何工作?负载均衡策略有哪些?如何限流?
    查看>>
    Nginx:NginxConfig可视化配置工具安装
    查看>>
    ngModelController
    查看>>
    ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
    查看>>
    ngrok内网穿透可以实现资源共享吗?快解析更加简洁
    查看>>
    NHibernate学习[1]
    查看>>
    NHibernate异常:No persister for的解决办法
    查看>>
    NIFI1.21.0_java.net.SocketException:_Too many open files 打开的文件太多_实际操作---大数据之Nifi工作笔记0051
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_补充_更新时如果目标表中不存在记录就改为插入数据_Postgresql_Hbase也适用---大数据之Nifi工作笔记0059
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>