朱刘算法
来源:互联网 发布:caffe训练googlenet 编辑:程序博客网 时间:2024/05/03 04:24
算法目的:求最小树形图(可以理解为有向图的最小有根生成树)
大概思路:用类似贪心的思想,不断缩点来求出答案。下面的算法可以求出当根确定的时候的最小树形图。如果是不定根的情况我们可以虚拟一个根,让虚拟根到每个节点的距离为图上所有边的权值之和加一。这样找到最小树形图一定包含且只包含一条新边,减掉这条边的权值就可以了。
算法步骤:1.求出所有点的最小入边
2.若此时这些边没有形成环,那么显然这些边就形成了最小树形图
3.将所有的环缩成一个点,对于环上所有的点X,把所有的(X,i,w)变成(new,i,w),所有的(i,X,w)变成(i,X,w-mn[X])
重复3,直到满足2条件
算法解析:3操作实际相当于先贪心的选择了所有的边,然后再决定删去哪一个。当再次选择一条指向这个环的边时,需要删除这个环上指向这个点的边,所以直接改变这些边的权值,把他们提前减去这个值就好了
int i,j,x,y,tn=-1; memset(mn,0x3f,sizeof(mn)); memset(vis,0,sizeof(vis)); memset(A,-1,sizeof(A)); EE.clear(); for(i=0;i<E.size();i++) { if(E[i].w<mn[E[i].y]) mn[E[i].y]=E[i].w,bef[E[i].y]=E[i].x; } for(i=0;i<n;i++) if(mn[i]==0x3f3f3f3f) return -1; int ti=0; for(i=0;i<n;i++) { ret+=mn[i]; x=i;ti++; while(x!=n&&!vis[x]) vis[x]=ti,x=bef[x]; if(x==n||vis[x]!=ti) continue; tn++; A[x]=tn; for(y=bef[x];y!=x;y=bef[y]) A[y]=tn; } if(tn==-1) return ret; for(i=0;i<=n;i++) if(A[i]==-1) tn++,A[i]=tn; for(i=0;i<E.size();i++) if(A[E[i].x]!=A[E[i].y]) EE.push_back((ppp){A[E[i].x],A[E[i].y],E[i].w-mn[E[i].y]}); E=EE; n=tn; }
0 0
- 朱刘算法模板
- 朱刘算法
- 朱刘算法
- 朱刘算法
- 朱刘算法
- 朱刘算法
- hdu4966 朱刘算法
- hdu2121(朱刘算法)
- 朱刘算法详解?
- 学习一个朱刘算法
- 最小树形图(刘朱算法)
- 最小树形图 模版--朱刘算法
- 最小树形图(朱-刘算法)
- 最小树形图(朱-刘算法)
- hdu4966 最小树形图 /刘朱算法
- 最小树形图 朱刘算法
- 最小树形图(朱-刘算法)
- Command Network - POJ 3164 朱刘算法
- “正被停用的激活上下文不是最近激活的”的错误的解决
- 支付宝在线支付
- js如何实现拆分字符串并依次输出
- Java Random类源码分析
- 【洛谷2022】 神奇数学题
- 朱刘算法
- R语言入门-R语言环境安装与Rstudio安装
- 基于Zookeeper的服务注册与发现
- C语言单链表
- 5. 数据结构
- webrtc:音频处理流程
- opengl DDA直线算法的实现
- JavaCC中扩展的正规表达式
- 对Linux多线程的理解