本文借鉴的博文: zephyr_pro dalao的blog

朱刘算法引入:
(把一道最小树形图当作最小生成树来做了,wa了后以为是bug像个sb一样d了半天)
最小树形图和最小生成树都是要求总权值最小,但区别是一个有向、一个无向。有向的最小树形图是不能用prim 或krustra算法来求解的。why?因为prim 或krustra算法只能适用无向图的环,不能适用有向图的环。

举个例子,如图:

图一是无向图,用prim或krustra算法求出的最小生成树总权值为1 + 3 + 2 = 6,而图二是有向图,他不是双向联通的,它用prim或krustra算法求出的最小树形图(树形图的根为1号节点)的总权值为1 + 3 + 4 = 8(这显然不对,正确的总权值应为1 + 4 + 2 = 7),到这里就应该了解了有向图和无向图的区别了,无向图是默认双向联通的,它可以很好的适用联通块思想,prim或krustra算法就是建立在联通块思想上的。而有向图因为有向所以不适用连通块思想,朱刘算法就是专门来解决最小树形图问题的。最小树形图其实就是有向图的最小生成树。

朱刘算法:

以下为主要算法流程:(不考虑缩点后的展开)

1,确定一个根

2,找到除根外每一个点的最小入边,若这些边构成了环(此时必然不联通),则缩环成点,并将环内的每一个点的其他入边都减去环内的入边,

3,重复步骤2直到没有环出现(构成了树)。

注意:
这是一个类似递归的过程,每次缩完点之后的点与其他点构成新图,不必考虑图是什么样的,我们只需要得到权值。这也是我之前陷入的一个误区。也就是说应当把缩完的点当做一个新点(正常的新点,不要和别的点分开,我们要平等的对待每一个点!)

一旦我们连上这条新边,这将意味着我们要放弃一条环内的边,显然树要求不能有2个父亲,因此我们要删去入边,但这并不好操作,

于是注意到我们的目标仅仅是权值,因此我们将每个点在环外入边的权值减去环内入边的权值,所以当我们连上一条新边时,

这样操作的实际效果在权值上和删去环内入边是等效的,只是减的地方不同而已,反正我们是求和。

放个百度百科上的图:

这个图就很好的表现出了朱刘算法解决最小树形图的算法过程。朱刘算法的精髓就是贪心加边压环成点减损补偿

hywc 的盗个dalao 的代码:

#include <cstdio>
#include <cstring>const int MAXNODE = 1010;
const int MAXEDGE = 100010;
typedef int Type;
const Type INF = 0x3f3f3f3f;struct Edge {int u, v;Type dis;Edge() {}Edge(int u, int v, Type dis): u(u), v(v), dis(dis) {}
};struct Directed_MT{int n, m;Edge edges[MAXEDGE];int vis[MAXNODE];int pre[MAXNODE];int id[MAXNODE];Type in[MAXNODE];void init(int n) {this->n = n;m = 0;}void AddEdge(int u, int v, Type dis) {edges[m++] = Edge(u, v, dis);}Type DirMt(int root) {Type ans = 0;while (1) {//初始化for (int i = 0; i < n; i++) in[i] = INF;for (int i = 0; i < m; i++) {int u = edges[i].u;int v = edges[i].v;//找寻最小入边,删除自环if (edges[i].dis < in[v] && u != v) {in[v] = edges[i].dis;pre[v] = u;}}//如果没有最小入边,表示该点不连通,则最小树形图形成失败for (int i = 0; i < n; i++) {if (i == root) continue;if (in[i] == INF) return -1;}int cnt = 0;//记录缩点memset(id, -1, sizeof(id));memset(vis, -1, sizeof(vis));in[root] = 0;//树根不能有入边for (int i = 0; i < n; i++) {ans += in[i];int v = i;//找寻自环while (vis[v] != i && id[v] == -1 && v != root) {vis[v] = i;v = pre[v];}//找到自环if (v != root && id[v] == -1) {//这里不能从i开始找,因为i有可能不在自环内for (int u = pre[v]; u != v; u = pre[u]) id[u] = cnt;id[v] = cnt++;}}//如果没有自环了,表示最小树形图形成成功了if (cnt == 0) break;//找到那些不是自环的,重新给那些点进行标记for (int i = 0; i < n; i++) if (id[i] == -1) id[i] = cnt++;for (int i = 0; i < m; i++) {int v = edges[i].v;edges[i].v = id[edges[i].v];edges[i].u = id[edges[i].u];if (edges[i].u != edges[i].v) edges[i].dis -= in[v];}//缩点完后,点的数量就边了n = cnt;root = id[root];}return ans;}
}MT;int main() {return 0;
}

生成树最小树形图 -- 朱刘算法详解相关推荐

  1. 最小树形图-朱刘算法详解 +例题解析

    文章目录 最小树形图 定义 和最小生成树的区别 朱刘算法 思想 步骤 流程展示 算法实现 例题 POJ3164_Command_Network HDU2121_Ice_cream's_world_II ...

  2. poj3164(最小树形图朱刘算法模板)

    题目链接:http://poj.org/problem?id=3164 题意:第一行为n, m,接下来n行为n个点的二维坐标, 再接下来m行每行输入两个数u, v,表点u到点v是单向可达的,求这个有向 ...

  3. 最小树形图——朱刘算法

    洛咕博客地址:−>ClickHere<−->Click Here<-−>ClickHere<−,求捧场 最近想找最小生成树的题做,奈何难度有限,点进的蓝题紫题都和& ...

  4. bzoj 4349: 最小树形图 朱-刘算法

    最裸的最小树形图(←现在才学的弱渣). 显然只需要打一下一个堡垒,然后剩下的可以最后用最小的代价再打. 然后只要把图建出来跑一下朱-刘算法即可. 简单讲一下朱-刘算法吧(思想还是很简单的),下面只考虑 ...

  5. NOIP模拟题 通讯 强连通分量缩点 最小树形图--朱刘算法

    通讯 (message.cpp\c\pas) [问题描述] "这一切都是命运石之门的选择." 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦 ...

  6. [UVA - 11865]Stream My Contest(最小树形图+朱刘算法)

    本题过于简单,朱刘算法模板题,考虑二分一下带宽即可 title code title code #include <cstdio> #include <cstring> #in ...

  7. 最小树形图(朱刘算法)

    不好意思 时间比较短,下面应该还会有修订的= = , 那段话是我复制过来的,觉得挺好的就用一下. 下面是讲解(不理解一的时候 , 可以看看二 ,结合图片): 一:   最小树形图,就是给有向带权图中指 ...

  8. 最小树形图+朱刘算法

    大题上完整的朱.刘算法是由四个大步骤组成的: 1.求最短弧集合E 2.判断集合E中有没有有向环,如果有转步骤3,否则转4 3.收缩点,把有向环收缩成一个点,并且对图重新构建,包括边权值的改变和点的处理 ...

  9. 最小树形图——朱刘算法学习小记

    参考资料: https://www.cnblogs.com/hdu-zsk/p/8167687.html https://www.luogu.com.cn/blog/xiaojiji/solution ...

最新文章

  1. 从字符串中删除HTML标签
  2. 2012-02-25工作记录
  3. 【内含福利】七牛云线下专场活动免费报名
  4. YBTOJ:字符匹配(KMP)
  5. 数据结构与算法(C#版)第二章 C#语言与面向对象技术(中)V1.0
  6. c是过程化语言吗数据库,关于SQL错误的是()A、所有数据库的公共语言B、非过程化的C、统一的语言D、所有用SQL缩写的程序都...
  7. 数据库自动备份脚本并删除前3天的备份
  8. 基于OpenCV与Dlib的行人计数开源实现
  9. 关于ElasticSearch整合SpringBoot
  10. Objective-C与JavaScript交互的那些事
  11. 通过CVE-2017-17215学习路由器漏洞分析,从入坑到放弃
  12. 基于java的康泰小区物业管理系统的设计与实现毕业设计源码101926
  13. 计算机课打字评课,三年级信息技术《键盘一家》评课稿
  14. 论文:Slicing Aided Hyper Inference and Fine-tuning for Small Object Detection通过划块的方式进行小目标检测
  15. ESP8266 +0.96“ I2C OLED 表盘时钟
  16. 工信部定级备案和等保备案有什么区别
  17. 论文笔记 | A Tale of Two Headers: A Formal Analysis ofInconsistent Click-Jacking Protection on the Web
  18. 超立方体(n方体)Qn:递推式 和 性质
  19. 尔雅课程解决网课鼠标移动问题教程
  20. (学习笔记) SPI通信协议

热门文章

  1. 如何理解C语言的声明
  2. Suzy想吃烤蛋挞了Day35 | 贪心算法进行时:860. 柠檬水找零,406. 根据身高重建队列,452. 用最少数量的箭引爆气球
  3. unity入门API————最常用的基类总结
  4. micropython里面外接tf(sd)卡读取模块
  5. TryHackMe学习笔记-Windows PrivEsc Arena
  6. 禁止安装第三方应用(可对某个应用特殊处理),动态通过暗码改变是否能够安装第三方应用。拨号中输入*#数字#进入指定界面。
  7. NV显卡 终于被我查到了
  8. 记一次艰难的SQL注入(过安全狗)
  9. 高手新手都能用的140个电脑技巧 收藏
  10. echarts cpu监控 心跳/心电图