最小生成树 & 无根树转有根树 & 树形动态规划

    • 最小生成树
      • 定义
        • 概念
        • 个人理解
      • 应用
      • 解决方法
        • 例题(luogu P3366 【模板】最小生成树)
          • 题目描述
          • 输入
          • 输出
        • 做法
          • 如何判环
          • 代码
    • 无根树转有根树
      • 方法
      • 将最小生成树(无根树)转化成有根树
        • 代码
    • 树形动态规划
      • 定义
      • 个人理解
      • 例题(luogu P1352 没有上司的舞会)
        • 题目描述
        • 解决
          • 代码
  • xiexie.

最小生成树

定义

概念

一个有 nnn 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 nnn 个结点,并且有保持图连通的最少的边。 —摘自百度百科

个人理解

最小生成树就是在一张图中找到一棵所有n−1n-1n−1条边的权值之和最小,最小生成树可能不止一棵。

应用

适用于城市之间最小费用等问题。

解决方法

例题(luogu P3366 【模板】最小生成树)

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz。

输入
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出
7

样例解释:

所以最小生成树的总边权为2+2+3=72+2+3=72+2+3=7.

做法

不难想到先将所有的权值从小到大排个序,然后最小的那条边一定是在最小生成树里面,当加入的这条边可以使当前的最小生成树出现环时,则跳过不能加进来。如果没有出现环,则把这条边加到这课最小生成树里,一直加到n−1n-1n−1条边加完为止(根据树的基本性质,所以nnn条边有n−1n-1n−1个点),这些操作完成后,这个最小生成树权值之和就是答案。

如何判环

利用并查集,将满足的边加入最小生成树时,同时加入同一个并查集(记录)。当不满足时,只需要判断点是否在并查集中,若在,则不能加进来,否则就加进来。

代码
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int n,m;
queue<int>q;
struct node1{int x,y,z;
}edge[200001];
struct Edges{int to,w;};
vector<Edges>d[5001];
void add(int a,int b,int c){d[a].push_back((Edges){b,c});d[b].push_back((Edges){a,c});
}
int cmp(node1 a,node1 b){return a.z < b.z;
}
int fa[5001];
int getfa(int x){if(x == fa[x])return x;return fa[x] = getfa(fa[x]);
}
int ans = 0,a[5001],tot;
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);}sort(edge+1,edge+m+1,cmp);for(int i=1;i<=n;i++)fa[i] = i;for(int i=1;i<=m;i++){if(getfa(edge[i].x)!=getfa(edge[i].y)){fa[getfa(edge[i].x)] = getfa(edge[i].y);ans+=edge[i].z;add(edge[i].x,edge[i].y,edge[i].z);}}printf("%d\n",ans);return 0;
}

无根树转有根树

这是一个技巧!
对于树形dp很有用。

方法

只要把无根树任意一个节点当成是根,然后遍历整个树即可。

将最小生成树(无根树)转化成有根树

题面方法同上。

代码

#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
int n,m;
queue<int>q;
struct node1{int x,y,z;
}edge[200001];
struct Edges{int to,w;};
vector<Edges>d[5001];
void add(int a,int b,int c){d[a].push_back((Edges){b,c});d[b].push_back((Edges){a,c});
}
int cmp(node1 a,node1 b){return a.z < b.z;
}
int fa[5001];
int getfa(int x){if(x == fa[x])return x;return fa[x] = getfa(fa[x]);
}
int ans = 0,a[5001],tot;
void dfs(int u,int pre){//该操作a[++tot]=u;for(int i=0;i<d[u].size();i++){int v = d[u][i].to;if(pre!=v) dfs(v,u);}
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);}sort(edge+1,edge+m+1,cmp);for(int i=1;i<=n;i++)fa[i] = i;for(int i=1;i<=m;i++){if(getfa(edge[i].x)!=getfa(edge[i].y)){fa[getfa(edge[i].x)] = getfa(edge[i].y);ans+=edge[i].z;add(edge[i].x,edge[i].y,edge[i].z);}}dfs(1,-1);printf("%d\n",ans);for (int i=1;i<=tot;i++) printf("%d ",a[i]);//输出有根树遍历return 0;
}

树形动态规划

定义

树形动态规划问题可以分解成若干相互联系的阶段,在每一个阶段都要做出决策,全部过程的决策是一个决策序列。要使整个活动的总体效果达到最优的问题,称为多阶段决策问题。 —摘自百度百科

个人理解

在图上动态规划,往往要在树上进行。

例题(luogu P1352 没有上司的舞会)

题目描述

某大学有 nnn 个职员,编号为 1…n1 \ldots n1…n。

他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。

现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数rir_iri​

,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。

所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

解决

根据建模类似线性动态规划得出状态转移方程。
我们设f[u][1]f[u][1]f[u][1]为当前人选择去的快乐值得最优情况。
f[u][0]f[u][0]f[u][0]为当前人不选去的快乐值得最优情况。
则:(vvv为当前点)
f[u][1]=∑f[v][0].f[u][1] = \sum{f[v][0]}. f[u][1]=∑f[v][0].
f[u][0]=∑max(f[v][0],f[v][1]).f[u][0] = \sum{max(f[v][0],f[v][1])}. f[u][0]=∑max(f[v][0],f[v][1]).
在这之前由题目可知需要先找根。

代码
#include<cstdio>
#include<vector>
using namespace std;
struct node{int to;};
vector<node>edges[6001];
int N,r[6001],sum,f[6001][2];
void dfs(int u){f[u][1] = r[u];for(int i=0;i<edges[u].size();i++){dfs(edges[u][i].to);f[u][1] += f[edges[u][i].to][0];f[u][0] += max(f[edges[u][i].to][0],f[edges[u][i].to][1]);}
}
int main(){scanf("%d",&N);for(int i=1;i<=N;i++){scanf("%d",r+i);sum ^= i;}for(int i=1;i<N;i++){int a,b;scanf("%d%d",&a,&b);edges[b].push_back((node){a});sum ^= a;}dfs(sum);printf("%d",max(f[sum][0],f[sum][1]));return 0;
}

答案就是max(f[sum][0],f[sum][1])max(f[sum][0],f[sum][1])max(f[sum][0],f[sum][1])

xiexie.

最小生成树 无根树转有根树 树形动态规划相关推荐

  1. 一本通提高篇 树形动态规划

    先写个考试 鸽着~ 考试有树 d p dp dp紫题 我回来了 每年联赛基本都有好几道题时树 d p dp dp,这块一定得好好学 U P D : 20201109 UPD:20201109 UPD: ...

  2. HDU1520 Anniversary party 树形动态规划

    HDU1520 Anniversary party 树形动态规划 Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  3. Facebook Hacker Cup 2015 Round 1--Corporate Gifting(树形动态规划)

    原题:https://www.facebook.com/hackercup/problems.php?pid=759650454070547&round=344496159068801 题意: ...

  4. 蓝桥杯 算法训练(四)结点选择(树形动态规划)

    结点选择(树形动态规划)C语言 问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一 ...

  5. c++ 不撞南墙不回头——树形动态规划(树规)

    不撞南墙不回头--树规总结                                         焦作一中信息学oy 之所以这样命名树规,是因为树规的这一特殊性:没有环,dfs是不会重复,而 ...

  6. 不撞南墙不回头——树形动态规划(树规)

    不撞南墙不回头--树规总结                                         焦作一中信息学oy 之所以这样命名树规,是因为树规的这一特殊性:没有环,dfs是不会重复,而 ...

  7. 假如我是儿子——树形动态规划

    --来自焦作一中卢裕东 想给这篇总结起个霸气又有意义的名字,翻来覆去,想到了今年暑假在郑州的NOIP夏令营,朱全民老师讲树规时说的一句惊天动地的话,那时给我们举例子,就有了这句:假如我是儿子!好吧,我 ...

  8. 小H和游戏(无根树转有根树,思维)难度⭐⭐⭐★

    链接:https://ac.nowcoder.com/acm/contest/5203/D 来源:牛客网 题目描述 小H正在玩一个战略类游戏,她可以操纵己方的飞机对敌国的N座城市(编号为1~N)进行轰 ...

  9. 树形动态规划之树的最大独立集

    树的最大独立集 对于一颗n个结点的无根树,选出尽量多的的结点,使得任何两个结点均不相邻(称为最大独立集),然后输入n-1条无向边,输出一个最大独立集(如果有多解,则任意输出一组). 分析: 用d(i) ...

  10. POJ2486POJ3659 ——树形动态规划

    两道题都折腾了很长时间,总算过了.树形动规,主要在于动规顺序,其次才是状态的设计. POJ2486: 先用左儿子右兄弟表示法进行多叉转二叉. f[i][j]表示从i点出发走了j步.最后不一定要回到i点 ...

最新文章

  1. sql中like带参数的写法
  2. IOS开发之--UIScrollView pagingEnabled自定义翻页宽度
  3. JavaME:Google静态地图API
  4. android蓝牙4.0使用方法
  5. resin指定java版本_resin的几个常用配置
  6. python特性 property_python之中特性(attribute)与属性(property)有什么区别?
  7. java图片简单爬虫_[Java教程]使用jsoup进行简单的爬虫操作爬取图片
  8. 选中连线的话,整个连线会显示在一个框里面
  9. 深入Hadoop磁盘部署的算法
  10. window10查看内存情况
  11. MENTOR PADS软件菜单显示不完整?这里有妙招
  12. ITIL学习笔记——ITIL入门小知识
  13. win10系统通过关键字快速搜索文件内容的软件
  14. 专升本-计算机公共课考点(5)——演示文稿软件 PowerPoint 2010
  15. mysql indentify_ORA-01157: cannot identify/lock data file导致表空间无法on
  16. Navigation网站收藏和导航平台
  17. python处理Excel实现自动化办公教学(数据筛选、公式操作、单元格拆分合并、冻结窗口、图表绘制等)【三】
  18. 天嵌i.mx6q开发板android4.3编译问题
  19. 问题 C: Fraction 分数类 I
  20. U盘写保护无法格式化

热门文章

  1. 论文阅读:Factorizable Net: An Efficient Subgraph-based Framework for Scene Graph Generation
  2. Excel中如何把数字设置成以万为单位
  3. 操作性定义(Operational Definition)
  4. Mathematica实现0.618法(黄金分割法)求最大最小值
  5. docker network详解、教程
  6. STM32单片机蜂鸣器实验
  7. 10分钟教你阿里云环境下搭建iredmail邮件服务器
  8. 安徽科技学院 信网学院网络文化节 陈鑫鑫
  9. 实验题集4:函数R6-1 面积计算器(函数重载) (10 分)
  10. 假设检验1——理论基础