当前位置: 首页 > news >正文

最小树形图:朱刘算法

最小树形图:朱刘算法

一.定义

无向图我们可以找到无向图的最小生成树,而有向图可不可以找到类似的东西呢?由此我们引入了最小树形图。

我们知道一个无向图的生成树中,每个点可以相互抵达,最小生成树就是树上权值和最小的生成树。因此我们定义一个树形图为根节点可以抵达所有点的树,而树上所有边都是从原图中选取而来(感觉说的比较迷糊)。当然所有树形图中权值最小的树形图就是最小树形图啦。

对于一个最小树形图来说,我们首先要选取一个根。最小树形图可能无解,这个用一个简单的DFS就可以判断。

二.DAG的最小树形图

我们显然发现在树形图中除了根 \(root\),其他每个点都有且仅有一条入边。

所以对于DAG来说,我们对于每个点选取最小的入边即可找到最小树形图。

证明显然:对于DAG不可能出现选择了环,而无环的有 \(n-1\) 条边的图一定是一棵树,且一定是最小的树形图,这个证明与Kruskal类似。

三.环的最小树形图

此处我们就考虑一个单纯的环上找最小树形图。

显然,我们可以从 \(root\) 开始转一圈删一条边即可。

四.朱刘算法

朱刘算法(Chu–Liu/Edmonds' algorithm)是算法领域少见的由中国人提出的算法,由朱永津和‌刘振宏于1965年提出。

我们考虑直接应用我们在DAG上提出的算法,我们发现这个算法选出来的边可能有两种可能:要么它就是构成了一棵树,那么这就是答案;要么它构成的图不联通,即存在环。

考虑环的处理。我们显然要把一条环边换成环外的边。

看到环,我们自然而然想到缩点,把这个环缩成一点。因为我们需要向这个环上连上一边,考虑如何连边。我们显然外向边的长度一定大于环内边的长度,因为我们选择的策略是贪心的。

\(ans\) 先加上这个环的边权和,然后我们把指向环的边的边权设成自己的长度减去所连向的环内点在环中指向的点的边的长度。

我们这样做显然就可以做到删掉一条不需要的边,使其权值可以很好地被抵消。

我们缩点之后,显然成了一张新的图,我们现在按DAG的方法求最小树形图。如果没环就是答案了,如果有环就是按照上述处理方法再继续跑下去。

五.注意事项

1.时间复杂度:\(O(VE)\)

2.要去掉重边和自环,否则时间复杂度会大大增加。

六.CODE

#include<bits/stdc++.h>
#define int long longusing namespace std;const int N=110,M=1e4+100,INF=1e18;int n,m,root;
struct EDGE{int u,v,w;
}edge[M];
int mn[N],fa[N],tp[N],lp[N];
int tot;
int ans;int zhuliu()
{while(true)//只要有环就一直跑{for(int i=1;i<=n;i++)mn[i]=INF,fa[i]=tp[i]=lp[i]=0;mn[root]=0;for(int i=1;i<=m;i++){if(edge[i].u!=edge[i].v && edge[i].w<mn[edge[i].v])mn[edge[i].v]=edge[i].w,fa[edge[i].v]=edge[i].u;}//Step1:找到最小的入边for(int i=1;i<=n;i++){ans+=mn[i];if(mn[i]==INF)  return -1;}//Step2:找到"DAG"的最小树形图for(int u=1,v=1;u<=n;u++,v=u){while(v!=root && tp[v]!=u && !lp[v])tp[v]=u,v=fa[v];if(v!=root && !lp[v]){lp[v]=++tot;for(int k=fa[v];k!=v;k=fa[k])   lp[k]=tot;}}//Step3:找环if(!tot) return ans;//Step4:无环,返回答案for(int i=1;i<=n;i++)if(!lp[i])lp[i]=++tot;for(int i=1;i<=m;i++)edge[i].w-=mn[edge[i].v],edge[i].u=lp[edge[i].u],edge[i].v=lp[edge[i].v];//Step5:缩点n=tot,root=lp[root],tot=0;}
}signed main()
{cin>>n>>m>>root;for(int i=1;i<=m;i++)cin>>edge[i].u>>edge[i].v>>edge[i].w;cout<<zhuliu()<<endl;return 0;
}
http://www.wuyegushi.com/news/567.html

相关文章:

  • 基于YOLOv8的边坡排水沟堵塞检测与识别项目|完整源码数据集+PyQt5界面+完整训练流程+开箱即用!
  • POLIR-Laws-民法典: 第三编 合同 : 第二分编 典型合同: 20.技术合同 : 1)一般规定、2)技术开发、3)技术转让 和 技术许可、4)技术咨询 和 技术服务
  • hybrid口
  • 利用Transformer模型提升产品检索效果
  • 第二十天
  • 《恶意代码实战分析》笔记
  • POLIR-Laws-民法典: 第三编 合同 : 第二分编 典型合同: 19.运输合同 : 1)一般规定、2)客运合同、3)货运合同、4)多式联运合同
  • 《大道至简》读后感
  • @GetMapping、@PostMapping、@PutMapping、@DeleteMapping
  • 建模神器草图大师!SketchUp 2025 安装激活全流程,新手也能玩转!
  • 【最新专业评测】PDF Reducer专业版:85%超高压缩率的PDF压缩神器|Windows最佳PDF压缩工具推荐
  • @RequestMapping
  • DMP学习路径之入门
  • 第一篇随笔
  • 旋转链表 - 商商
  • 匀速二阶贝塞尔曲线
  • Redis原理
  • HTTP POST请求:初学者指南与示范
  • @Autowired 自动依赖注入
  • 基于接口划分vlan
  • 【AirSim】图像API的使用
  • CSS页面布局
  • switch 语句
  • 优秀书籍随记
  • Golang 文本模板,你指定没用过
  • @RestController
  • Django实时通信实战:WebSocket与ASGI全解析(下)
  • DP 优化——决策单调性优化
  • VS插件报错,g++却完美编译?API调用错因分析
  • 《构造之法》读后感