- 1、本文档共12页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
树的最大连通分支问题 问题描述: 给定一棵树T,树中每个顶点u都有一个权w(u),权可以是负数。现在要找到树T的一个连通子图使该子图的权之和最大。 对于给定的树T,编程计算树T的 最大连通分支。 编程任务: 第1行有1个正整数n,表示树T有n个顶点。 树T的顶点编号为1,…,n。 第2行有n个整数,表示n个顶点的权值。 接下来的n-1行中,每行有表示树T的一条 边的2个整数u,v,表示顶点u与顶点v相连。 数据输入: 由文件input.txt给出输入数据。 结果输出: 将计算出的最大连通分支的权值输出 到文件output.txt。 input.txt: 5 -1 1 3 1 -1 4 1 1 3 1 2 4 5 输入文件示例: 1 2 3 4 5 -1 3 1 -1 1 最大连通分支 连通图 连通图中各结点的权值之和最大 输出文件示例: output.txt: 4 1 2 3 4 -1 3 1 1 树根 root T1 T2 W0 W0 最大连通分支在子树或树中,因此对树进行遍历,依次求出以每个结点为树根的最大连通分支权值。 Wr=Wr+Wt1 root T1 T2 W0 W0 算法分析: … … 问题具有两个子性质: 最优子结构性质 子问题重叠性质 树根 root T1 T2 W0 W0 … 算法实现: 1 2 3 4 5 3 1 -1 1 树根 -1 对于叶子结点或儿子个数为0的 结点,其最大连通分支权值为该 结点的权值 某一结点的最大连通权值>0, 则将其值加到它的父亲结点的最 大连通权值,反之舍弃该值 最后求出根结点的最大连通权 值,结束遍历 所求最大连通分支权值即结点中 的最大连通权值 数据结构 struct Cnode { long weight; //结点的权值 int father; //该结点的父亲结点 int childnum; //结点的儿子数 long wMax; //结点的最大连通分支的权值 bool visited; //该结点是否被访问过 }; weight father childnum wMax visited 动态创建数组表示树 Cnode *tree=new Cnode[n+1]; 存储记录初始化及数据输入 for (i=1;i=n;i++) { tree[i].father=0; tree[i].childnum=0; tree[i].visited=false; fin(tree[i].weight); 算法步骤(1) for (i=1;i=(n-1);i++) { finuv; tree[v].father=u; tree[u].childnum++; } tree[i].wMax=tree[i].weight; } 确定树根 for (i=1;i=n;i++) if (tree[i].father==0) root=i; 遍历树,求出每个结点的wMax while (tree[root].childnum)0 { for (i=1;i=n;i++) if ((tree[i].childnum==0)(!tree[i].visited) { tree[i].visited=1; tree[tree[i].father].childnum--; if (tree[i].wMax0) tree[tree[i].father].wMax=tree[tree[i].father].wMax+tree[i].wMax; } } 求出最大的连通分支权值 算法步骤(2) 最大时间复杂性:O(n2)
文档评论(0)