本文共 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以示例中的树为例,取节点1为根节点,分层后权值累加过程如下:
#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/